正在获取特定类型的记录
本文关键字:类型 记录 获取 | 更新日期: 2023-09-27 18:00:40
我有两个类:
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和两个DB集。基本上,BaseItem是一个根类,它下面有一个子项树。DB将包含几十个这样的树
实体框架将只为两个类创建一个表,我不喜欢,但目前已经足够了。(我能告诉EF用一种简单的方法把它分成两张表吗?)
我的问题是只选择根项,因此选择BaseItem类的任何项,而不选择ChildItem类的项。类似的东西
db.Items.Where(i=>i.GetType()==typeof(BaseItem))
这将不起作用,因为EF无法将GetType方法转换为对数据库有意义的方法。所以我要么在Where子句之前加一个.ToList()
,要么找到一个更好的解决方案
由于我不想在过滤掉500个根项目之前检索所有1000000条记录,所以我需要更好的解决方案。什么是更好的解决方案?
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; }
}
由于涉及继承,可能有一个针对您存储的实体的类型描述符,您可以对其进行筛选,并且它看起来就像您只有一个表,您有一个名为"逐层次表(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>()
方法,可能会让你出价。
EDIT(已更正为工作示例)
使用类似于的用法
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]}