EntityFramework - Code First - FluentAPI
实体类最好能是保持与架构无关性的POCO类,才能更具通用性。
所以,最好是在数据层中使用FluentAPI在数据层中进行实体类与数据库之间的映射工作。
使用 构建器(FluentAPI) 或者 标注(DataAnnotations)
1. 尽量用 构建器 来完成数据库的约束
2. 使用 标注 来丰富模型的验证规则
使用方法:
public class User { [Key] public Guid ID { get; set; } public string 姓名 { get; set; } public Guid 岗位编号 { get; set; } [ForeignKey("岗位编号")] public virtual Quarter 岗位 { get; set; } }
protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Configurations.Add(new UserConfiguration()); base.OnModelCreating(modelBuilder); }
public class UserConfiguration : EntityTypeConfiguration<User> { public UserConfiguration() { ToTable("User"); //指定schema,不使用默认的dbo ToTable("User","newdbo"); //普通主键 HasKey(p => p.Id); //关联主键 HasKey(p => new {p.Id, p.Name}); //不让主键作为Identity自动生成 Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); //非空,最大长度20,自定义列名,列类型为varchar而非nvarchar Property(p => p.Name).IsRequired().HasMaxLength(20).HasColumnName("ProductName").IsUnicode(false); Ignore(p => p.Name); } }
如果希望今后增加一个配置就更改一次 OnModelCreating 方法的话, 可以利用反射, 将所有继承自 EntityTypeConfiguration<> 的类都注册起来
var typesToRegister = Assembly.GetExecutingAssembly().GetTypes() .Where(type => !String.IsNullOrEmpty(type.Namespace)) .Where(type => type.BaseType != null && type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>)); foreach (var type in typesToRegister) { dynamic configurationInstance = Activator.CreateInstance(type); modelBuilder.Configurations.Add(configurationInstance); }
基本方法:
ToTable:指定映射到的数据库表的名称。.
HasKey:配置主键(也用于配置关联主键).
Property:这个方法返回PrimitivePropertyConfiguration的对象,根据属性不同可能是子类StringPropertyConfiguration的对象。通过这个对象可以详细配置属性的信息如IsRequired()或HasMaxLength(400)。
Ignore:指定忽略哪个属性(不映射到数据表)