C# EF Core 5.0带子选择的Union Linq查询不工作
目标: 我想将两个具有不同属性的表entityA和entityB中的信息合并到一个unionDto中。我试图通过联合操作来实现这一点,以同时过滤数据库中的不同实体 但是我使用的结构需要在联合查询之前过滤版本 一些补充资料: 因此,我在上一个查询中尝试做的是:首先,我将表entityA和entityB中的信息投影到具有union的通用匿名类型。然后我尝试应用分页,然后我尝试将新的匿名结果投影到UnionDto。因此,这将产生一个UnionDto,其中包含来自两个不同表的信息 我创建了两个实体的问题示例,这两个实体具有以下版本: 实体: 我似乎无法在联合查询中使用子选择,并且出现以下错误: 设置操作:在中放置在客户端评估之后时提供支持 投影16243 我不知道,我必须做些什么来绕过这个问题,因为我真的不想用单独的数据库查询来分别检查我的所有实体 目前使用的Ef核心版本:5.0.100-preview 这只是一个例子。这至少需要10个实体,如果单独为每个实体执行,将导致高数据库流量C# EF Core 5.0带子选择的Union Linq查询不工作,c#,postgresql,linq,entity-framework-core,ef-core-5.0,C#,Postgresql,Linq,Entity Framework Core,Ef Core 5.0,目标: 我想将两个具有不同属性的表entityA和entityB中的信息合并到一个unionDto中。我试图通过联合操作来实现这一点,以同时过滤数据库中的不同实体 但是我使用的结构需要在联合查询之前过滤版本 一些补充资料: 因此,我在上一个查询中尝试做的是:首先,我将表entityA和entityB中的信息投影到具有union的通用匿名类型。然后我尝试应用分页,然后我尝试将新的匿名结果投影到UnionDto。因此,这将产生一个UnionDto,其中包含来自两个不同表的信息 我创建了两个实体的问题
有什么想法吗?如果您只需要每个记录集中第一个版本的标题,您的查询可以简化,EF Core可以翻译此查询
var queryA =
from entity in databaseContext.Set<entityA>()
from version in entity.Versions
where version.EffectiveTo > now
select new
{
Title = version.Title,
Creator = entity.CreatedBy
}
var queryB =
from entity in databaseContext.Set<entityB>()
from version in entity.Versions
where version.EffectiveTo > now
select new
{
Title = version.Title,
Creator = entity.CreatedBy
}
var versions = queryA.Union(queryB);
var unionDto = await versions
.Skip(0)
.Take(20)
.Select(x => new UnionDto
{
Title = x.Title,
Creator = x.Creator,
})
.ToListAsync();
你想干什么?这个查询有点复杂,不会返回您认为会返回的结果。在所有当前支持的SQL Server版本中,您可以使用时态表,而不是添加和维护有效列。即使您确实需要单独的有效记录与有效记录,ORM也不是应用临时筛选的地方。您应该为此使用视图。除此之外,EF Core 5还引入了过滤功能。您可以使用透明的时间过滤。ORM的工作是将对象映射到关系表或视图。它并不意味着实现触发器、临时过滤、报告查询和批量操作。LINQ使报告查询更容易一些,但只是在一定程度上。你应该考虑在LINQ或SQL中写这个查询是否有意义,使用你的数据库的完整特性设置,如果你从子查询中选择.TistRIST会发生什么?或者,如果您在不进行过滤的情况下对实体进行公共化,然后过滤公共实体,该怎么办?e、 g.延迟Where。选择联合后的to?此查询很难翻译。这里有两个急切的加载查询,它们很难组合,我甚至无法想象这种情况下的通用解决方案。考虑将您的查询重写为两个分离的查询。在您选择的选择中没有X.标题。谢谢您的建议,但是这样做会导致以下错误:当前对不同存储类型的操作不支持。所以我查看了这个错误消息,看起来ef Core目前不支持这个操作。我能说什么呢。EF仍然是弱LINQ转换器,甚至错误消息也很奇怪。让我们重写查询。用新查询更新了答案。谢谢您的帮助,但看起来这也不起作用。同样的错误。看起来,通常不可能在这些联合查询中使用Subselect,因此我将被迫为此编写一个manuall SQL查询。我知道,这是可能的,但我试图避免使用Linq。使用Linq是可能的,只是EF与Union失败。只要试试我的扩展,就可以享受正确生成的SQL。
var queryA = databaseContext.Set<entityA>()
.Select(entity => new
{
Versions = entity.Versions
.Where(version => version.EffectiveTo > now) /* Filtering newest entity Version */
.Select(versionDetail => new /* Selecting only the Title of this Version */
{
Title = versionDetail.TitleA
})
.ToList(),
Creator = entity.CreatedBy,
});
var queryB = databaseContext.Set<entityB>()
.Select(entity => new
{
Versions = entity.Versions
.Where(version => version.EffectiveTo > now)
.Select(versionDetail => new
{
Title = versionDetail.TitleB
})
.ToList(),
Creator = entity.CreatedBy,
});
var unionDto = await queryA
.Union(queryB)
.Skip(0)
.Take(20)
.Select(x => new UnionDto
{
Title= x.Versions.FirstOrDefault() == null ? null :
x.Versions.FirstOrDefault().Title,
Creator= x.Creator,
})
.ToListAsync();
var queryA =
from entity in databaseContext.Set<entityA>()
from version in entity.Versions
where version.EffectiveTo > now
select new
{
Title = version.Title,
Creator = entity.CreatedBy
}
var queryB =
from entity in databaseContext.Set<entityB>()
from version in entity.Versions
where version.EffectiveTo > now
select new
{
Title = version.Title,
Creator = entity.CreatedBy
}
var versions = queryA.Union(queryB);
var unionDto = await versions
.Skip(0)
.Take(20)
.Select(x => new UnionDto
{
Title = x.Title,
Creator = x.Creator,
})
.ToListAsync();