获取特定类型的记录

时间:2014-04-29 15:37:01

标签: c# types visual-studio-2013 poco entity-framework-6

我有两个班级:

public class BaseItem
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public virtual List<ChildItem> Children { get; set; }
}
public class ChildItem : BaseItem
{
    public virtual BaseItem Parent { get; set; }
    public ChildItem() { }
}

我为这两个类创建了一个DBContext和两个DBSets。基本上,BaseItem是一个根类,其下面有一个子项树。数据库将包含数十个这样的树 实体框架将为这两个类创建一个表,我不喜欢,但现在它已经足够好了。 (我可以告诉EF以简单的方式将其分成两个表吗?)

我的问题是只选择根项,因此选择类BaseItem而不是类ChildItem。像

这样的东西
db.Items.Where(i=>i.GetType()==typeof(BaseItem))

这不起作用,因为EF无法将GetType方法转换为对数据库有意义的方法。所以我要么在Where子句之前加.ToList(),要么找到更好的解决方案 由于我不想在过滤500个根项目之前检索所有1,000,000条记录,因此我需要更好的解决方案。什么是更好的解决方案?

这是定义DBContext(db变量)和DBSet(db的Items属性)的方式。

 public class Datamodel : DbContext
    {
        public Datamodel() : base("name=Datamodel") { }
        public virtual DbSet<BaseItem> Items { get; set; }
        public virtual DbSet<ChildItem> Children { get; set; }
    }

1 个答案:

答案 0 :(得分:1)

由于涉及继承,可能存在针对您存储的可以过滤的实体的类型描述符,并且看起来您只有一个表,您有一个名为Table Per Hierachy(TPH)的排列

检查此链接:

http://weblogs.asp.net/manavi/archive/2010/12/24/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-1-table-per-hierarchy-tph.aspx

它指的是OfType<T>()方法,可以进行出价。

编辑(更正为工作示例)

使用类似:

var rootItems = context.Items.OfType<BaseItem>().Except(context.Items.OfType<ChildItem>());

在TPH场景中只撤回根项目。

SQL:

SELECT 
1 AS [C1], 
[Except1].[Discriminator] AS [C2], 
[Except1].[Id] AS [C3], 
[Except1].[Name] AS [C4], 
[Except1].[Parent_Id] AS [C5]
FROM  (SELECT 
    [Extent1].[Discriminator] AS [Discriminator], 
    [Extent1].[Id] AS [Id], 
    [Extent1].[Name] AS [Name], 
    [Extent1].[Parent_Id] AS [Parent_Id]
    FROM [dbo].[BaseItems] AS [Extent1]
WHERE [Extent1].[Discriminator] IN (N'ChildItem',N'BaseItem')
EXCEPT
    SELECT 
    N'ChildItem' AS [C1], 
    [Extent2].[Id] AS [Id], 
    [Extent2].[Name] AS [Name], 
    [Extent2].[Parent_Id] AS [Parent_Id]
    FROM [dbo].[BaseItems] AS [Extent2]
    WHERE [Extent2].[Discriminator] = N'ChildItem') AS [Except1]}