首页 文章

EF Code First One To Many(使用“普通”表)

提问于
浏览
0

考虑以下示例:

一个人可以有多个地址 . 商店可以有多个地址 . 两者都有1:M到地址表 .

使用EF6,Code First,如何设置我的实体和映射(FluentApi)来支持这个?根据我使用EF 1:M的经验,子表(地址)对于其父表(Person或Store)是唯一的 . 我会有一个Person Table和一个具有1:M关系的PersonAddressTable . 我还有一个Store和StoreAddress表,它们有自己的1:M关系 . 对我来说不幸的是,现有的数据模型是以这种方式编写的 .

我的理解是我通过在子实体上添加一个指向父节点的nav属性来定义1:M关系 . 子实体还必须具有指向父项的ID字段(FK),并且必须在子实体上将此FK属性标记为必需 .

所以在我的例子中,地址实体会有

public virtual Person Person {get;set;}
public int PersonId {get;set;    
public Virtual Store Store {get;set;}
public int StoreId {get;set;

并且Address实体映射器将定义:

this.Property(i=>i.PersonId).IsRequired();
this.Property(i=>i.StoreId).IsRequired();

this.HasRequired(p=>p.Person)
.WithMany(c=>c.Addresses)
.HasForeignKey(c=>PersonId);

this.HasRequired(p=>p.Store)
.WithMany(c=>c.Addresses)
.HasForeignKey(c=>c.StoreId);

但是,根据其父级,子导航属性(Person或Store)将为null . 引用Person的地址时,Address.Store nav属性将为null,并且在引用商店的地址时,Address.person nav属性将为null .

我怎样才能正确定义这些关系?

谢谢 .

2 回答

  • 1

    我不知道如何使用FluentAPI,但这是使用CodeFirst进行此操作的一种方法 .

    注意,Store和Person引用Address,而不是相反 .

    我会有以下三个类:

    public class AddressModel
    {
        public int AddressId { get; set; }
        public string Line1 { get; set; }
        public string Line2 { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string Zip { get; set; }
    }
    
    public class PersonModel
    {
        public int PersonId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public List<AddressModel> Addresses { get; set; }
    }
    
    public class StoreModel
    {
        public int StoreId { get; set; }
        public string StoreName { get; set; }
        public List<AddressModel> Addresses { get; set; }
    }
    
  • 0

    首先,不能立即清楚您是否掌控了基础表,或者您是否遇到现有表 . 假设您确实拥有对表的控制权并且只想将所有地址映射到单个表,则可以使用TPH执行此操作 .

    请在下面找到如何设置它的示例 .

    public class AppContext : DbContext
        {
            public DbSet<Person> People { get; set; }
            public DbSet<Store> Stores { get; set; }
            public DbSet<Address> Addresses { get; set; }
        }
    
        public class Person
        {
            public Person()
            {
                Addresses = new HashSet<PersonAddress>();
            }
            public int Id { get; set; }
            public string Name { get; set; }
            public virtual ICollection<PersonAddress> Addresses { get; set; }
    
        }
    
        public class Store
        {
            public Store()
            {
               Addresses = new HashSet<StoreAddress>();
            }
            public int Id { get; set; }
            public string StoreName { get; set; }
    
            public virtual ICollection<StoreAddress> Addresses { get; set; }
    
        }
    
        public abstract class Address
        {
            public int Id { get; set; }
            public string AddressInformation { get; set; }
        }
    
        public class PersonAddress : Address
        {
            public string PersonAddressInformation { get; set; }
        }
    
        public class StoreAddress : Address
        {
            public string StoreAddressInformation { get; set; }
        }
    

    从中生成的数据库表看起来像这样 .

    TPH Table Diagram

相关问题