EF6 Code First继承和外来关系取决于鉴别器值

时间:2014-12-12 20:10:45

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

目前我正在使用代码优先方法编写应用程序,我需要创建两个非常相似的实体,让我们说代表地址所以我创建了:

public abstract class BaseEntity
{
    public Guid Id { set; get; }
}

public abstract class Address : BaseEntity
{
    public string Discriminator { set; get; }

    public Guid ObjectId { set; get; }

    public Guid CountryId { set; get; }

    public virtual Country Country { set; get; }

    public string Town { set; get; }

    public string PostalCode { set; get; }

    public string Street { set; get; }

    public string BuildingNumber { get; set; }

    public string FlatNumber { get; set; }

    public AddressType AddressType { get; set; }

    public bool IsDefault { get; set; }
}

然后我有两个继承自Address类的类,如下所示:

public class UserAddress : Address
{
    public virtual User User { set; get; }
}

public class ContractorAddress : Address
{
    public virtual Contractor Contractor { set; get; }
}

现在我需要让我的模型构建器将抽象类中ObjectId属性的值映射到两个不同的类(对于UserAddress,它应该指向User.Id值,而用户导航属性应该使用此值,对于ContractorAddress,它应指向Contractor.Id值,Contractor导航属性应使用此值) 我想使用Table per Hierarchy(TPH)方法。

我的问题是,如何在模型构建器中描述这些关系?

1 个答案:

答案 0 :(得分:0)

为映射添加配置类。对于TPH使用:

class AddressConfiguration : EntityTypeConfiguration<Address>
{
    public AddressConfiguration()
    {
        Map<UserAddress>(m => m.Requires("AddressType").HasValue("user"));
        Map<ContractorAddress>(m => m.Requires("AddressType").HasValue("contractor"));
    }
}

至于关系:

class UserAddressConfiguration : EntityTypeConfiguration<UserAddress>
{
    public UserAddressConfiguration()
    {
        HasRequired(m => m.User).WithMany().HasForeignKey(m => m.ObjectId);
    }
}
class ContractorAddressConfiguration : EntityTypeConfiguration<ContractorAddress>
{
    public ContractorAddressConfiguration()
    {
        HasRequired(m => m.Contractor).WithMany().HasForeignKey(m => m.ObjectId);
    }
}

映射您的其他属性应该非常简单。最后将您的配置添加到模型构建器:

modelBuilder.Configurations.Add(new AddressConfiguration());
modelBuilder.Configurations.Add(new UserAddressConfiguration());
modelBuilder.Configurations.Add(new ContractorAddressConfiguration());

请注意,TPH表示您的实体映射到一个表,因此您有一个列ObjectId引用2个不同的表。我建议你从基类中删除ObjectId,将UserId和ContractorId添加到子类中并映射你的关系。