EF6 TPH mapping of derived property to specific ta

2019-08-15 08:40发布

问题:

Have legacy DB with a Customer entity split in into 3 tables (1-1) with shared key. Wanted to use Code First TPH and map it to split tables. Here's simplified classes hierarchy (numerous primitive properties and their mappings omitted):

public abstract partial class Customer
{
    public int Id { get; set; }
    public bool Leasing { get; set; }
    public string Address { get; set; }
    public string Name { get; set; }
}

class PrivateCustomer : Customer
{
    public string PrivateName { get; set; }
}

class CorporateCustomer : Customer
{
    public string CompanyName { get; set; }
}

And here's how I try to map it across 3 tables:

public class CustomerMap : EntityTypeConfiguration<Customer>
{
    public CustomerMap()
    {
        Map<CorporateCustomer>(m => m.Requires("ClientType").HasValue(2))
            .Map<PrivateCustomer>(m => m.Requires("ClientType").HasValue(1));

        // Primary Key
        HasKey(t => t.Id);

        // Table & Column Mappings
        Map(m =>
        {
            m.ToTable("CustomerSet");
            m.Properties(p => new
            {
                p.Id,
                p.Leasing,
                //p.PrivateName
            });
        });

        Map(m =>
        {
            m.ToTable("SiriusCustomer");
            m.Properties(p => new
            {
                p.Id,
                p.Address
            });
            m.Property(p => p.Id).HasColumnName("AccessUserId");
            m.Property(p => p.Address).HasColumnName("SiriusAddres");
        });

        Map(m =>
        {
            m.ToTable("AccessUser");
            m.Properties(p => new
            {
                p.Id,
                p.Name,
                //p.CompanyName
            });

            m.Property(p => p.Id).HasColumnName("AccessUserId");
            m.Property(p => p.Name).HasColumnName("AccessUserName");
            //m.Property(p => p.CompanyName).HasColumnName("AccessUserCompany");
        });
    }
}

But I don't know how to manually map PrivateName and CompanyName to desired columns in desired tables. Is that possible? Thanks.

回答1:

Well here's the closest I've managed to reach. But with the limitation that derived properties should be mapped to the same table. Otherwise determination column will be created in each table which is useless.

public class CustomerMap : EntityTypeConfiguration<Customer>
{
    public CustomerMap()
    {
        // Primary Key
        HasKey(t => t.Id);

        // Table & Column Mappings

        Map<PrivateCustomer>(m =>
        {
            m.ToTable("AccessUser");
            m.Properties(p => p.PrivateName);
            m.Requires("ClientType").HasValue(1);
        });

        Map<CorporateCustomer>(m =>
        {
            m.ToTable("AccessUser");
            m.Properties(p => p.CompanyName);
            m.Requires("ClientType").HasValue(2);
            m.Property(p=>p.CompanyName).HasColumnName("AccessUserCompany");
        });


        Map(m =>
        {
            m.ToTable("CustomerSet");
            m.Properties(p => new
            {
                p.Id,
                p.Leasing,
            });
        });

        Map(m =>
        {
            m.ToTable("SiriusCustomer");
            m.Properties(p => new
            {
                p.Id,
                p.Address
            });
            m.Property(p => p.Id).HasColumnName("AccessUserId");
            m.Property(p => p.Address).HasColumnName("SiriusAddres");
        });

        Map(m =>
        {
            m.ToTable("AccessUser");
            m.Properties(p => new
            {
                p.Id,
                p.Name,
            });

            m.Property(p => p.Id).HasColumnName("AccessUserId");
            m.Property(p => p.Name).HasColumnName("AccessUserName");
        });
    }
}