我们在使用EF CodeFirst 模式生成数据库的时候进行表的代码映射关系可以采用注解模式和Fluent API模式。这里就是记录一下使用Fluent API进行表关系映射的方法。
注解模式:
回顾一下我们以前都知道的注解模式,一个表,在表的字段上和表上增加相应的注解进行映射即可:
[Table("SysErrorLogInfor")] public partial class SysErrorLogInfor { [Key] public string id { get; set; } [Required] //必填 public int userId { get; set; } [MinLength(10)]//最小长度 public string userName { get; set; } [MaxLength]//最大长度 public string logLevel { get; set; } public string logMessage { get; set; } public DateTime? addTime { get; set; } public int? delFlag { get; set; } }
Fluent API
那么我们如果同样使用Fluent API模式改如何实现哪,首先我写这个不是说Fluen API 比注解模式好,只是做个简单比较。不过使用Fluen API 模式可以使对象表更纯洁化。更加的整洁,但是同样的因为整洁了,少了很多东西,就需要在别的地方增加相应的东西。
你不写数据库是不知道你这个字段要干嘛是什么作用,有那些限制的。
还是刚才的那张表,现在改成这个样:
public partial class SysErrorLogInfor { public string id { get; set; } public int userId { get; set; } public string userName { get; set; } public string logLevel { get; set; } public string logMessage { get; set; } public DateTime? addTime { get; set; } public int? delFlag { get; set; } }
很清晰,这张表只为了表明当前表所存在那些字段和类型,但是具体的字段限制是不能辨别的。刚才也说了少一些东西必然增加一些东西,所有为了让映射知道我字段有那些限制我们还是要指定表的字段,那就要在创建一个规则类(这就是多出来的):
我们创建一个SysErrorLogInforMap类,这里此类需要基础 EntityTypeConfiguration<T>泛型所有需要添加引用:using System.Data.Entity.ModelConfiguration;
然后在该类的构造函数中设置SysErrorLogInfor表其中的属性字段代码如下:
public class SysErrorLogInforMap : EntityTypeConfiguration<SysErrorLogInfor> { public SysErrorLogInforMap() { //配置属性字段 Property(t => t.id).HasMaxLength(32); Property(t => t.userName).HasMaxLength(50); Property(t => t.logLevel).HasMaxLength(50); //配置表名 ToTable("SysErrorLogInfor"); } }
这样你就对SysErrorLogInfor表设置了一个规则类,然后我们只需要启动这个规则就可以了,我们在上下文中的OnModelCreating方法中启动此规则,启动规则可以单个表的启用也可以全部启用(在表多的情况下):
注意:在OnModelCreating方法中配置Fluent API
Code First配置优先顺序为:Fluent API > DataAnnotations > default conventions
protected override void OnModelCreating(DbModelBuilder modelBuilder) { //手动加载 //modelBuilder.Configurations.Add(new SysErrorLogInforMap()); //全部加载 modelBuilder.Configurations.AddFromAssembly(Assembly.GetExecutingAssembly()); }
配置方法
配置的规则非常多,我就不列举所有了你可以通过代码查看所有只说比较常用的几个
HasKey:配置主键
Property:配置那个属性,这个一般都是会在其后跟随配置的其他一个规则例如上面的之后跟随一个长度限制
HasMaxLength:最大长度
IsFixedLength:固定为多少位
IsOptional:将属性配置为可选属性。用于存储此属性的数据库列将可以为 null。
IsRequired:将属性配置为必需属性。用于存储此属性的数据库列将不可以为 null。
IsUnicode:将属性配置为支持 Unicode 字符串内容。
HasColumnName: 配置用于存储属性的数据库列的名称,这个我觉得就是一个是在代码中的属性名然后可以设置为数据库列名不同。
HasColumnType:配置用于存储属性的数据库列的数据类型,这个非常有用因为c#设置的string类型在映射到数据会自动成nvarchar(int)类型这个可以指定为varchar(int)类型,截图说明:
数据库策略问题
这里特别注意哦:配置表名那个地方如果你不写的话,加入你的EF模式配置的是关闭数据库生成策略的话你会发现意向不到的意外哦因为数据库的默认生成策略是复数形式所有当你启用关闭数据库生成策略的时候你会查不到表的错误。
当然你也不必像上面那样每个表都配置表名,可以在直接使用提供的方法关闭复数策略形式:
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
关闭数据库生成策略代码示例:
public BaseDBContent() : base("name=Entity") { Database.SetInitializer<BaseDBContent>(null); }
其他策略:
数据库不存在时重新创建数据库
Database.SetInitializer(new CreateDatabaseIfNotExists<BaseDBContent>());
每次启动应用程序时创建数据库(其实默认的不做任何配置就是会自动创建数据库的)
Database.SetInitializer(new DropCreateDatabaseAlways<BaseDBContent>());
模型更改时重新创建数据库
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<BaseDBContent>());
禁用关系数据的级联删除
// 禁用一对多级联删除 modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>(); // 禁用多对多级联删除 modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
禁用延迟加载(Lazy Loading)
// 禁用延迟加载 this.Configuration.LazyLoadingEnabled = false;
Code First默认规则
表及列默认规则:EF Code First默认生成的表名为类名的复数形式
主键约束:实体类中属性名为Id或[类名]Id,将作为生成表的主键。若主键为int类型,则默认为Sql Server的Identity类型
字符类型属性:实体类中string类型的属性,在生成表时,对应Sql Server中nvarchar(max)类型
Byte Array类型约束:实体类中byte[]类型的属性,生成表时对应Sql Server中varbinary(max)类型
Boolean类型约束:实体类中bool类型的属性,在生成表是对应Sql Server中bit类型