- Conventions 都定义在 System.Data.Entity.ModelConfiguration.Conventions 命名空间下,就是一系列的规则(约束)的集合
- 通俗的讲就是定义数据库里面字段
- 一般我们在约束字段时可以使用Data Annotations 或者 Fluent API 或者Conventions,荐的配置顺序如下:优先使用 Data Annotations ,然后是 Fluent API ,最后才是 Conventions.
1. 类型发现 约束
通俗的说就是让DbConntext 知道我们定义的数据实体,一般做法是自定义一个Context继承与DbConntext,同时定义DbSet属性
public class SwartzUserUserContext : DbContext
{
public SwartzUserUserContext() : base("UserContext")
{
}
类型发现 约束
public DbSet<MUserInfo> UserInfo { get; set; }
.....
}
Code First 能够发现并钻取所有的引用类型,如上代码中的MUserInfo 实体如果用引用类型的属性,该属性也会自动包含在模型中,如果不想让某个实体包含进去,可以使用NotMappdeAttribute或者DbModelBuilder.Ignore(fluent API)实现
[NotMapped]
public class Department
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Ignore<Department>();
}
2. 主键约束
如果实体中的属性名称为ID(不区分大小写)或类名+ID,Code First 会默认其为主键,如果主键属性的类型为int或GUID 则会默认为标识列
3. 关系(外键)约束
- 一对多关系
public class MUserInfo
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public MOrgInfo OrgInfo { get; set; }
}
public class MOrgInfo
{
[Key]
public int ID { get; set; }
public string Name { get; set; }
public int Address { get; set; }
public List<MUserInfo> Users { get; set; }
}
如上代码,MUserInfo中有一个MOrgInfo对象,MOrgInfo有一个MUserInfo中有一个MOrgInfo对象集合对象,所以MOrgInfo和MUserInfo是一对多关系,所以CodeFirst在生成数据库时会自动为MUserInfo添加外键(MOrgInfoID)
其实只要一个类中存在引用属性(MOrgInfo OrgInfo),或存在导航属性(List Users),CodeFirst 都会自动生成外键(OrgInfo_ID、MOrgInfoID )
指定外键:
只要外键名命名规范的话,CodeFirst 也会将该属性设置为外键,如下
public class MUserInfo { [Key] public int ID { get; set; } public string Name { get; set; } public int Age { get; set; } //会自动设置为外键 也可以是MOrgInfoID、MOrgInfoMOrgInfoID public int OrgInfoMOrgInfoID { get; set; } public MOrgInfo OrgInfo { get; set; } }
规范的命名指:[目标类型的键名],[目标类型名称]+[目标类型键名称],[导航属性名称]+[目标类型键名称]即MOrgInfoID、OrgInfoMOrgInfoID、MOrgInfoMOrgInfoID
如果命名不规范的话,可以显示的指定外键[ForeignKey("OrgInfo")] public int OrgID { get; set; } public MOrgInfo OrgInfo { get; set; }
或
public int OrgID { get; set; } [ForeignKey("OrgID")] public MOrgInfo OrgInfo { get; set; }
当然也可以使用Fluent Api 指定外键
modelBuilder.Entity<MUserInfo>().HasRequired(u => u.OrgInfo).WithMany(o => o.Users).HasForeignKey(u => u.OrgID);
对同一个实体的多个引用
http://www.cnblogs.com/Gyoung/archive/2013/01/22/2869782.html public class MOrgInfo { [Key] public int ID { get; set; } public string Name { get; set; } public int Address { get; set; } public List<MUserInfo> GoodUser { get;set; } public List<MUserInfo> BadUser { get; set; } } public class MUserInfo { [Key] public int ID { get; set; } public string Name { get; set; } public int Age { get; set; } public int OrgInfoID { get; set; } public MOrgInfo OrgInfoGood { get; set; } public MOrgInfo OrgInfoBad { get; set; } }
这样的话MUserInfo会生成4个外键,因为有两套类型的导航属性和引用属性,codefirst 无法确定他们之间的关系,就为每个属性都创建,为了让codefirst知道对应关系,可以使用InverseProperty
[InverseProperty("GoodUser")] public MOrgInfo OrgInfoGood { get; set; } [InverseProperty("BadUser")] public MOrgInfo OrgInfoBad { get; set; }
这样的话就只有两个外键咯
- 多对多关系
两个实体中都有对方的导航属性,这时会自动生成一张中间表,存两个实体的主键
- 一对一关系
两个实体中都有对方的引用属性,这时必须显示的指定依赖关系public class Person { public int PersonId { get; set; } public PersonPhoto Photo { get; set; } } public class PersonPhoto { [Key, ForeignKey("PhotoOf")] public int PersonId { get; set; } public byte[] Photo { get; set; } public Person PhotoOf { get; set; } }
这时 PersonPhoto表中的PersonId既是外键也必须是主键
4.复杂类型约束
如果 Code First 无法从类定义中推断出主键,也没有通过 Data Annotations 或 Fluent API 注册的主键,则此类型自动注册为复杂类型。 此外还要求类型中不能含有对其它实体类型的引用,并且其它类型中也不能含有对本类型引用的属性集合
public partial class OnsiteCourse : Course { public OnsiteCourse() { Details = new Details(); } public Details Details { get; set; } } public class Details { public System.DateTime Time { get; set; } public string Location { get; set; } public string Days { get; set; } }
Details 就是一个复杂类型
5.移除约定
可以移除任何定义于命名空间 System.Data.Entity.ModelConfiguration.Conventions 中的约定
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
参考资料:
http://msdn.microsoft.com/en-us/data/jj679962
http://www.cnblogs.com/CreateMyself/p/4773886.html?utm_source=tuicool&utm_medium=referral