如何为具有多个父类型的子场景编写EF代码的第一个映射

时间:2011-12-11 10:09:29

标签: c# entity-framework orm ef-code-first code-first

我有4个课程。供应商,客户,员工和地址。前3种类型中的任何一种都可以具有“n”个地址。所以这些类看起来像这样;

class Address 
{
    int Id { get; set; }
    int ParentId { get; set; }  // NOTE: This is the FK.
    IAggregateRoot Parent { get; set; } // EXAMPLE: Supplier, Customer, Employee ..

    // rest of the address fields.
}

class Supplier : IAggregateRoot
{
    int Id { get; set; }
    virtual List<Address> Addresses { get; set; }

    // rest of the supplier details.

    AddAddress(Address address)
    {
        address.Parent = this;
        address.ParentId = this.Id;

        Addresses.Add(address);
    }
}

class Customer : IAggregateRoot
{
    int Id { get; set; }
    virtual List<Address> Addresses { get; set; }

    // rest of the customer details.

    AddAddress(Address address)
    {
        address.Parent = this;
        address.ParentId = this.Id;

        Addresses.Add(address);
    }
}

class Employee : IAggregateRoot
{
    int Id { get; set; }
    virtual List<Address> Addresses { get; set; }

    // rest of the employee details.

    AddAddress(Address address)
    {
        address.Parent = this;
        address.ParentId = this.Id;

        Addresses.Add(address);
    }
}

如何编写Address的Parent属性的映射?或者更好的方法/设计来做这种情况?

3 个答案:

答案 0 :(得分:2)

您如何期望EF在数据库中解决这样的映射? Address.ParentId列是否会引用Customer,Supplier或Employee的主键?

如果你摆脱从地址到IAggregateRoot的导航,你可能能够做到这一点。也许试试这个:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Employee>.HasMany(p => p.Addresses).WithOptional()
        .Map(d => d.MapKey("EmployeeId"));
    modelBuilder.Entity<Supplier>.HasMany(p => p.Addresses).WithOptional()
        .Map(d => d.MapKey("SupplierId"));
    modelBuilder.Entity<Customer>.HasMany(p => p.Addresses).WithOptional()
        .Map(d => d.MapKey("CustomerId"));
}

答案 1 :(得分:0)

如果员工,客户和供应商不共享父实体(类)并且不遵循继承映射,则不能这样做。对于每个相关实体,您的地址必须具有单独的关系,如@olivehour所述。

答案 2 :(得分:0)

来自对OP的评论:

  

我不希望每个Parent类型都有很多Address类。不,我不想查询/导航从地址到父。

您的域逻辑或用户工作流程中是否存在某些内容会使多个父级共享同一地址成为真实场景?如果除非他们同时登录并交换信息面对面,否则地址共享的事实是否会以非常重要的方式显示在用户界面中?

如果没有,我不确定两个相同的地址是否共享相同的ID真的很重要,我不确定潜在的数据重复是否重要。

在这种情况下,我推荐KISS。

创建三个单独的映射表,不要为任何继承而烦恼,并调用它:)

SupplierToAddressMap:
SupplierId  AddressId

CustomerToAddressMap:
CustomerId  AddressId

EmployeeToAddressMap:
EmployeeId  AddressId