EF关系规则

参考文章:http://www.cnblogs.com/feigao/p/4617442.html

Entity Framework 实体间的关系,一对一,一对多,多对多,根据方向性来说又分为双向和单向。Code First在实体关系上有以下约定

1. 两个实体,如果一个实体包含一个引用属性,另一个实体包含一个集合属性,Code First默认约定它们为一对多关系。
2. 两个实体,如果只有一个实体包含一个导航属性或一个集合属性,Code First也默认约定它们是一对多关系。
3. 两个实体分别包含一个集合属性,Code First默认约定它们为多对多关系。
4. 两个实体分别包含一个引用属性,Code First默认约定它们为一对一关系。
5. 在一对一关系情况下,需要提供给Code First额外的信息,以确定它们的主从关系。
6. 在实体中定义一个外键属性,Code First使用属性是否为空来确定关系是必须还是可选

 

一对一:

以产品和保修卡为例,一个产品对应一个保修卡,产品和保修卡使用相同的产品编号

产品类

   

public class Product
    {
        public int Id { get; set; }
        /// <summary>
        /// 产品名字
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// 描述
        /// </summary>
        public string Description { get; set; }
        /// <summary>
        /// 保修卡
        /// </summary>
        public virtual WarrantyCard WarrantyCard { get; set; }
}

 

保修卡类:

   

public class WarrantyCard
    {
        public int ProductId { get; set; }
        public DateTime ExpiredDate { get; set; }
        public virtual Product Product { get; set; }
    }
public class WarrantyCardMap : EntityTypeConfiguration<WarrantyCard>, IEntityMapper
    {
        public WarrantyCardMap()
        {
            ToTable("WarrantyCard");
            HasKey(i => i.ProductId);
        }
        public void RegistTo(System.Data.Entity.ModelConfiguration.Configuration.ConfigurationRegistrar configurations)
        {
            configurations.Add(this);
        }
    }

 

  public class ProductMap : EntityTypeConfiguration<Product>, IEntityMapper
    {
        public ProductMap()
        {
            ToTable("Product");
            HasKey(p => p.Id);
            HasRequired(p => p.WarrantyCard).WithRequiredPrincipal(i => i.Product);
            HasOptional(p => p.WarrantyCard).WithRequired(i => i.Product);
        }
    }

 

Product作为Principal(主)而WarrantyCard作为Dependent

 

一对一(可空):

以产品和发票为例,有些产品可能没有发票

发票类:

public class Invoice
{
    public int Id { get; set; }
    public string InvoiceNo { get; set; }   
    public DateTime CreateDate { get; set; }
}

产品类新增

public virtual Invoice Invoice { get; set; }
public int? InvoiceId { get; set; }

ProductMap中配置

HasOptional(p => p.Invoice).WithMany().HasForeignKey(p => p.InvoiceId);

HasOptional表示可空,WithMany()中没有参数标识不需要从发票关联到产品

一对多:

以产品和照片为例:

产品照片类:

 public class ProductPhoto
    {
        public int Id { get; set; }
        public string FileName { get; set; }
        public float FileSize { get; set; }
        public virtual Product Product { get; set; }
        public int ProductId { get; set; }
    }

 

Product类增加ProductPhoto集合:

public virtual ICollection<ProductPhoto> Photos { get; set; }

ProductMap中配置

HasMany(p => p.Photos).WithRequired(pp => pp.Product).HasForeignKey(pp => pp.ProductId);
public class ProductPhotoMap : EntityTypeConfiguration<ProductPhoto>,IEntityMapper
    {
        public ProductPhotoMap()
        {
            ToTable("ProductPhoto");
            HasKey(pp => pp.Id);

        }
        public void RegistTo(System.Data.Entity.ModelConfiguration.Configuration.ConfigurationRegistrar configurations)
        {
            configurations.Add(this);
        }
}

HasMany表示Product中有多个ProductPhotoWithRequired表示ProductPhoto一定会关联到一个Product

多对多:

产品和产品标签,一个产品可以有多个标签,一个标签也可对应多个产品

标签类:

  

 public class Tag
    {
        public int Id { get; set; }

        public string Text { get; set; }

        public virtual ICollection<Product> Products { get; set; }
    }

 

Product增加标签集合

        /// <summary>
        /// 标签
        /// </summary>
        public virtual ICollection<Tag> Tags { get; set; }

ProductMap中添加配置:

HasMany(p => p.Tags).WithMany(t => t.Products).Map(m => m.ToTable("Product_Tag_Mapping"));
public class TagMap : EntityTypeConfiguration<Tag>,IEntityMapper
    {
        public TagMap()
        {
            ToTable("Tag");

            HasKey(t => t.Id);
        }
        public void RegistTo(System.Data.Entity.ModelConfiguration.Configuration.ConfigurationRegistrar configurations)
        {
            configurations.Add(this);
        }
    }