C# 当EF6使用逐层次表(TPH)映射策略时,父实体中具有派生类的多个集合不起作用

C# 当EF6使用逐层次表(TPH)映射策略时,父实体中具有派生类的多个集合不起作用,c#,inheritance,entity-framework-6,table-per-hierarchy,tph,C#,Inheritance,Entity Framework 6,Table Per Hierarchy,Tph,这个周末我花了大半时间想弄明白这一点 我有一个包含订阅表的现有数据库,我希望使用TPH继承策略将其映射到域中的实体 订阅有几种类型,每种类型都有自己的特点,因此需要继承。以下是该域的简化版本: public class Subscription { public int CustomerID { get; set; } public virtual Customer Customer { get; set; } public int SubscriptionID { ge

这个周末我花了大半时间想弄明白这一点

我有一个包含订阅表的现有数据库,我希望使用TPH继承策略将其映射到域中的实体

订阅有几种类型,每种类型都有自己的特点,因此需要继承。以下是该域的简化版本:

public class Subscription
{
    public int CustomerID { get; set; }
    public virtual Customer Customer { get; set; }
    public int SubscriptionID { get; set; }
    public string Name { get; set; }
}
public class BookSubscription:Subscription
{
    public string Book { get; set; }
}
public class TVSubscription : Subscription
{
    public string Channel { get; set; }
}
这些实体在上下文中映射如下:

public DbSet<Customer> Customers { get; set; }
public DbSet<Subscription> Subscriptions { get; set; }
public DbSet<TVSubscription> TVSubscriptions { get; set; }

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Customer>().ToTable("tblCustomer");
    modelBuilder.Entity<Customer>().HasKey(t => t.CustomerID);

    modelBuilder.Entity<Subscription>()
            .Map<Subscription>(m =>
            {
                m.ToTable("tblSubscription");
                m.Requires("ServiceTypeId").HasValue(1);
            })
             .Map<TVSubscription>(m =>
             {
                 m.Requires("ServiceTypeId").HasValue(20);
             })
            .Map<BookSubscription>(m =>
            {
                m.Requires("ServiceTypeId").HasValue(5);
            }
            );
    modelBuilder.Entity<Subscription>().HasKey(s => s.SubscriptionID);

    base.OnModelCreating(modelBuilder);
}
公共数据库集客户{get;set;}
公共数据库集订阅{get;set;}
公共数据库集订阅{get;set;}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
modelBuilder.Entity().ToTable(“tblCustomer”);
modelBuilder.Entity().HasKey(t=>t.CustomerID);
modelBuilder.Entity()
.Map(m=>
{
m、 ToTable(“TBL认购”);
m、 需要(“ServiceTypeId”).HasValue(1);
})
.Map(m=>
{
m、 需要(“ServiceTypeId”).HasValue(20);
})
.Map(m=>
{
m、 需要(“ServiceTypeId”).HasValue(5);
}
);
modelBuilder.Entity().HasKey(s=>s.SubscriptionID);
基于模型创建(modelBuilder);
}
正如所料,当为任何派生类查询上下文时,EF使用ServiceTypeId作为鉴别器正确构造查询。当我试图在客户实体中包含派生类时,问题就出现了。这项工作:

public class Customer
{
    public int CustomerID { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Subscription> Subscriptions{ get; set; }      
}
公共类客户
{
public int CustomerID{get;set;}
公共字符串名称{get;set;}
公共虚拟ICollection订阅{get;set;}
}
这不起作用:

public class Customer
{
    public int CustomerID { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Subscription> Subscriptions{ get; set; }
    public virtual ICollection<TVSubscription> TvSubscriptions { get; set; }
}
公共类客户
{
public int CustomerID{get;set;}
公共字符串名称{get;set;}
公共虚拟ICollection订阅{get;set;}
公共虚拟ICollection订阅{get;set;}
}
这也不是:

public class Customer
{
    public int CustomerID { get; set; }
    public string Name { get; set; }

    public virtual ICollection<TVSubscription> TvSubscriptions { get; set; }
}
公共类客户
{
public int CustomerID{get;set;}
公共字符串名称{get;set;}
公共虚拟ICollection订阅{get;set;}
}
当我检查profiler时,我可以看到在这两种情况下,EF都添加了_id后缀,并尝试查询除customerID之外不存在的customer_id列。我曾尝试显式映射派生类型的外键,但EF当时抱怨:

外键组件“CustomerID”不是类型“TVSubscription”上声明的属性。验证它是否未从模型中明确排除,并且它是一个有效的基元属性

CustomerID在派生类中并没有位置,但即使我尝试将其移动到那个里,它也不起作用(我怀疑是因为EF当时正试图使用另一种继承策略进行映射)

现在,我明白我可以这样做:

public IEnumerable<TVSubscription> TvSubscriptions
{
    get { return Subscriptions.OfType<TVSubscription>(); }
}
public IEnumerable订阅
{
获取{return Subscriptions.OfType();}
}
但是,使用这种方法,EF查询数据库中的整个订阅集,然后在本地对其进行过滤,以仅返回订阅。这当然不理想,因为客户可以有数百个订阅,我希望EF只查询并返回特定类型的订阅,就像我使用dbContext时已经做的那样

所以问题是,我如何在Customer类中包含TVSubscriptions列表,并仅对这些订阅进行EF查询

若这是不可能的,那个么当我将派生类集合添加到客户实体时,有人能解释一下EF正在做什么样的假设吗