从对基础的请求中排除派生实体 class

Exclude derived entities from requests to the base class

我有这个 DbContext:

public class DataContext : DbContext
{
    public DbSet<Base> Bases {get;set}
    public DbSet<Sub> Subs {get;set}
}

SubBase 的子类。

当我像这样查询基本实体列表时:

Context.Bases.ToListAsync()

它 returns 我每个实体,BaseSub

如何配置我的模型上下文以仅获取 Base 类型的实体,而不是从它派生的实体。

How can I configure my model context to get only the entities that are of Base type and not the ones that derives from it.

你不能。每个 Sub 一个 Base。因此查询所有 Bases 包括所有 Subs。例如像下面这样的代码必须成功:

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

您可以获取仅具有基本 class 属性的匿名类型。

问这个问题表明继承可能不是适合您的场景的正确建模技术。

如果您希望它获取 Base 类型的实体,但 不是 子类型 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,会在客户端过滤掉子类型。

你必须使用 OfType<T>:

var basesOnly = await _context.Bases.OfType<Base>().ToListAsync();

更新

那么抱歉。我本可以发誓上述作品,但事实并非如此。我能想到的下一个最佳方法是简单地过滤掉不需要的类型。这并不理想,因为它需要在您的查询中指定所有子类型,这意味着如果您添加更多子类型,您需要记得更新它。

var basesOnly = await _context.Bases.Where(x => !(x is Sub)).ToListAsync();

我找到的最好(或最差)的解决方案是直接使用阴影 属性:

Context.Bases.Where(b => EF.Property<string>(b, "Discriminator") == "Base")).ToListAsync();

它有效,但需要不时重复,每次我需要查询 Bases。我更喜欢 OnModelCreating 方法中的解决方案。

除非其他人找到更好的解决方案,否则我会接受这个答案。