当前位置:首页 > 技能相关 > .NET > 正文内容

EFCore:DBContext的基本配置

admin1年前 (2023-12-25).NET4520 修订时间:2023-12-25 21:06:09

1、概述与OnConfiguring、OnModelCreating方法

除非你的数据库已经存在,否则不推荐使用反向工程来通过数据库创建模型,一般推荐使用CodeFirst模式,即代码先行的原则。在DBContext类中,最重要,也是我们最常用的两个方法就是:"OnConfiguring"和 “OnModelCreating”。参考文章: Entity Framework Code初体验

1.1 OnConfiguring

此方法可以自己进行数据库的配置,以及其他选项的配置。其中主要有以下常用的配置:配置连接字符串、配置输出的Logger、配置过滤和拦截操作、禁用和启用并发等;

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
  if (!optionsBuilder.IsConfigured)
  {
    optionsBuilder.UseMySql("server=b.lifeiai.com;user id=EFStudent;password=lf123456;database=efstudent", Microsoft.EntityFrameworkCore.ServerVersion.Parse("5.6.50-mysql"));//连接字符串
    optionsBuilder.LogTo(Console.WriteLine);//日志输出到控制台
    optionsBuilder.AddInterceptors(new SoftDeleteInterception()); //添加拦截器软删除
    optionsBuilder.EnableThreadSafetyChecks(false);//关闭并安全检测

  }
}

1.2 OnModelCreating

可以对实体类也可以说是数据表进行模型配置。模型配置主要分为两种方法:FluentAPI、数据注解

1.2.1在OnModelCreating里使用的是fluentAPI

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
            modelBuilder.UseCollation("utf8_general_ci")
                .HasCharSet("utf8");

            modelBuilder.Entity<Student>(entity =>
            {
                entity.Property(e => e.Class).HasMaxLength(50);

                entity.Property(e => e.Name).HasMaxLength(50);
            });
}

1.2.2 采用FluentAPI配置实体类有两种方式:

一、通过上面介绍的在OnModelCreating里进行配置。

二、创建实现了IEntityTypeconfiguration接口的实体类,然后再在OnModelCreating方法里添加如下方法:

modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly)

示例:

<1>新建一个实体类Student

public class Student
{
    public long Id { get; set; }
    public string Name { get; set; }
    public string Class { get; set; }
    public int Age { get; set; }
    public string Sex { get; set; }
}

<2>新建一个学生配置类:

public class StudentConfig : IEntityTypeConfiguration<Student>
{
        public void Configure(EntityTypeBuilder<Student> builder)
        {
            //设置主键
            builder.HasKey(x => x.Id); 
            //设置Id自增
            builder.Property(x => x.Id).ValueGeneratedOnAdd();
            //设置姓名最大长度为50,字符为unicode,不能为空
            builder.Property(x=>x.Name).HasMaxLength(50).IsUnicode().IsRequired();
            //设置班级最大长度为50,字符为unicode,不能为空
            builder.Property(x=>x.Class).HasMaxLength(50).IsUnicode().IsRequired();
            //设置性别最大长度为5 字符为Unicode,不能为空
            builder.Property(x=>x.Sex).HasMaxLength(5).IsUnicode().IsRequired();
        }
}

<3>在EFLearnDbContext中的OnModelCreating里添加下面的代码

 protected override void OnModelCreating(ModelBuilder modelBuilder)
{     
   modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
}

也可直接按如下代码配置

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
            //设置主键,并自增
            modelBuilder.Entity<Student>().HasKey(x=>x.Id);
            modelBuilder.Entity<Student>().Property(x => x.Id).ValueGeneratedOnAdd();

            //设置姓名最大长度为50,字符为unicode,不能为空
            modelBuilder.Entity<Student>().Property(x => x.Name).HasMaxLength(50).IsUnicode().IsRequired();

            //设置班级最大长度为50,字符为unicode,不能为空
            modelBuilder.Entity<Student>().Property(x => x.Class).HasMaxLength(50).IsUnicode().IsRequired();

            //设置性别最大长度为5 字符为Unicode,不能为空
            modelBuilder.Entity<Student>().Property(x => x.Sex).HasMaxLength(5).IsUnicode().IsRequired();
}

1.2.3 其他方式(数据注解)

除了上述方法,还可以直接在类上配置,例如:

 public class Student
{
        [Key] //主键
        public long Id { get; set; }
        
        [MaxLength(50)]   //最大长度为50
        [Unicode]         //字符
        [Required]        //不能为空
        public string Name { get; set; }

        [MaxLength(50)]   //最大长度为50
        [Unicode]         //字符
        [Required]        //不能为空
        public string Class { get; set; }
}

数据注解的方式 优点:简单方便;缺点:耦合性太高;
FluentAPI 优点:解耦; 缺点: 编写复杂

2.Fluent API配置模型

2.1表和列的配置

EFCore默认采用和类一样的名称创建表名字,按照类的属性名称创建表中列的名称,如果需要不同的名称,可以采用下面的方法:

//NewStudent 对应着 Student表
//注解方法
[Table("Student")]
public class NewStudent
//FluentAPI方法
modelBuilder.Entity<NewStudent>().ToTable("Student");
 
//IsFemale 对应着 Gender 列
//注解方法
[Column("Gender")]
public bool IsFemale { get; set; }
//FluentAPI方法
modelBuilder.Entity<NewStudent>().Property(s => s.IsFemale).HasColumnName("Gender");

//列注释信息
//注解方法
[Comment("学生学号")]
public string Id{ get; set; }
//FluentAPI
modelBuilder.Entity<Student>().Property(b => b.Id)
            .HasComment("学生学号");
            
//列类型,注解方法
[Column(TypeName = "varchar(200)")]
modelBuilder.Entity<Student>().Property(b => b.Name)
            .HasColumnType("varchar(200)")

默认情况下,在使用迁移创建表时,EF Core 首先为主键列排序,然后为实体类型和从属类型的属性排序,最后为基类型中的属性排序,也可如下指定排序:

//注解方法
[Column(Order = 0)]
public int Id { get; set; }
[Column(Order = 1)]
public int Name{ get; set; }
//FluentAPI
modelBuilder.Entity<Employee>(x =>
{
    x.Property(b => b.Id)
     .HasColumnOrder(0);
    x.Property(b => b.Name)
     .HasColumnOrder(1);
});

2.2 约束性配置

最大长度 字符串或者数组类型最大的长度

//最大长度 字符串或者数组类型最大的长度
//注解方法   / FluentAPI
[MaxLength(500)]  / HasMaxLength(500);

//精度和小数位数
[Precision(14, 2)]/HasPrecision(14, 2)

//Unicode 和非 Unicode 文本数据
[Unicode(false)]/IsUnicode(false)

//必需和可选属性
[Required]/IsRequired()

//忽略,标记模型某个属性可以使该属性不必映射到数据库。
[NotMapped]/.Ignore()

2.3 键的配置

在EFCore约定中没有显示的指定键,那么默认名为 类名+Id结尾 的属性将被配置为实体的主键。

//注解方法   / FluentAPI
[Key]/HasKey(c => c.Id)

组合键(多个属性配置为实体的键),只能使用 Fluent API 进行配置:

modelBuilder.Entity<Student>().HasKey(c => new { c.Id, c.Nmae});

2.4自增和默认设置

//注解方法   / FluentAPI
//自增
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]   /   ValueGeneratedOnAdd();

//默认值
HasDefaultValue(3);    /   .HasDefaultValueSql("getdate()");

2.5 关系配置

描述实体类型(表)之间的关系,大部分只能用FluentAPI,如下:

.HasOne(b => b.BlogImage).WithOne(i => i.Blog);//一对一
.HasOne(p => p.Blog).WithMany(b => b.Posts); //一对多
.HasMany(p => p.Tags).WithMany(p => p.Posts);//多对多

2.6 索引

//注解方法   / FluentAPI
//单一索引
[Index(nameof(Url))] / HasIndex(b => b.Url);

//复合索引
[Index(nameof(FirstName), nameof(LastName))]  /  .HasIndex(p => new { p.FirstName, p.LastName });

//唯一索引
[Index(nameof(Url), IsUnique = true)]  /  .HasIndex(b => b.Url).IsUnique();

还以一些不是太常用的配置,可以参考微软的官方文档查看。LINK

 您阅读本篇文章共花了: 

免责声明
本站内容均为博客主本人日常使用记录的存档,如侵犯你的权益请联系:lifei@zaiheze.com 546262132@qq.com 沟通删除事宜。本站仅带访问端口形式使用,已杜绝搜索引擎爬取。

扫描二维码推送至手机访问。

版权声明:本文由LIFEI - blog发布,如需转载请注明出处。

本文链接:http://www.lifeiai.com/?id=347

分享给朋友:

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。