简体   繁体   中英

EF6 CodeFirst inheritance and foreign relation dependent on discriminator value

Currently I am writing an application using code first approach, and I need to create two very similar entities, lets say representing address so I've created:

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; }
}

And then I have two classes which inherits from Address class like so:

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

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

Now I need to make my model builder to map value of ObjectId property in abstract class to two different classes (for UserAddress it should points to User.Id value and User navigation property should use this value, for ContractorAddress it should points to Contractor.Id value and Contractor navigation property should use this value) I want to use Table per Hierarchy (TPH) approach.

My question is, how should I describe those relations in model builder?

Add configuration classes for your mappings. For TPH use:

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

As for the relations:

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);
    }
}

Mapping your other properties should be pretty straight forward. Finally add your configurations to the model builder:

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

Note that TPH means your entities are mapped to one table, so you have one column ObjectId referencing 2 different tables. I would recommend you remove ObjectId from your base class, add UserId and ContractorId to the subclasses and map your relations with those.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM