CodeFirst(二)Conventions

  1. Conventions 都定义在 System.Data.Entity.ModelConfiguration.Conventions 命名空间下,就是一系列的规则(约束)的集合
  2. 通俗的讲就是定义数据库里面字段
  3. 一般我们在约束字段时可以使用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. 关系(外键)约束

  1. 一对多关系
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; }

这样的话就只有两个外键咯

  1. 多对多关系
    两个实体中都有对方的导航属性,这时会自动生成一张中间表,存两个实体的主键
  1. 一对一关系
    两个实体中都有对方的引用属性,这时必须显示的指定依赖关系
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

posted @ 2019-01-24 17:38  Pen丶  阅读(242)  评论(0编辑  收藏  举报