我有这个DbContext:
public class DataContext : DbContext
{
public DbSet<Base> Bases {get;set}
public DbSet<Sub> Subs {get;set}
}
Sub
是Base
的子类。
当我像这样查询基本实体列表时:
Context.Bases.ToListAsync()
它返回我每个实体,Base
或Sub
。
如何配置我的模型上下文,使其仅获取Base
类型的实体,而不从其派生的实体。
答案 0 :(得分:1)
如何配置我的模型上下文以仅获取以下实体 基本类型,而不是其基础类型。
您不能。每个Sub 都是一个基础。因此,查询所有库都包括所有子库。像下面这样的代码必须成功:
Base b = db.Bases.Where(i => i.Id == 1).Single();
if (b is Sub)
begin
Sub s = (Sub)b;
. . .
end
else //other Sub
begin
Sub2 s = (Sub2)b;
. . .
end
您可以仅使用基类属性来获取匿名类型。
问这个问题建议,继承可能不是适合您的方案的建模技术。
如果您希望它获取Base类型的实体,而Sub类型不是Sub的 ,则可以使用以下查询来做到这一点:
var q = from b in db.Bases
where !(b is Sub)
select b;
翻译为:
SELECT [b].[Id], [b].[Discriminator], [b].[Name], [b].[Size]
FROM [Bases] AS [b]
WHERE [b].[Discriminator] IN (N'Sub', N'Base')
AND NOT ([b].[Discriminator] = N'Sub')
但是(当前)您不能(如果没有)枚举所有子类型。例如此查询:
var q2 = from b in db.Bases
where b.GetType() == typeof(Base)
select b;
不会完全转换为SQL,并且会过滤掉客户端上的子类型。
答案 1 :(得分:1)
您必须使用OfType<T>
:
var basesOnly = await _context.Bases.OfType<Base>().ToListAsync();
更新
那么,很抱歉。我本可以宣誓以上作品,但事实并非如此。我能想到的下一个最佳方法是简单地过滤掉不需要的类型。这不是理想的,因为它需要在查询中指定所有子类型,这意味着如果您添加更多子类型,则需要记住对其进行更新。
var basesOnly = await _context.Bases.Where(x => !(x is Sub)).ToListAsync();
答案 2 :(得分:1)
我发现最好的(或最差的)解决方案是直接使用shadow属性:
Context.Bases.Where(b => EF.Property<string>(b, "Discriminator") == "Base")).ToListAsync();
它可以工作,但是每次我需要查询Bases
时,都需要不时重复。我本来希望使用OnModelCreating
方法中的解决方案。
除非有人找到更好的解决方案,否则我会接受这个答案。