Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# EF Core 5.0带子选择的Union Linq查询不工作_C#_Postgresql_Linq_Entity Framework Core_Ef Core 5.0 - Fatal编程技术网

C# EF Core 5.0带子选择的Union Linq查询不工作

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,其中包含来自两个不同表的信息 我创建了两个实体的问题

目标:

我想将两个具有不同属性的表entityA和entityB中的信息合并到一个unionDto中。我试图通过联合操作来实现这一点,以同时过滤数据库中的不同实体

但是我使用的结构需要在联合查询之前过滤版本

一些补充资料:

因此,我在上一个查询中尝试做的是:首先,我将表entityA和entityB中的信息投影到具有union的通用匿名类型。然后我尝试应用分页,然后我尝试将新的匿名结果投影到UnionDto。因此,这将产生一个UnionDto,其中包含来自两个不同表的信息

我创建了两个实体的问题示例,这两个实体具有以下版本:

实体:

我似乎无法在联合查询中使用子选择,并且出现以下错误:

设置操作:在中放置在客户端评估之后时提供支持 投影16243

我不知道,我必须做些什么来绕过这个问题,因为我真的不想用单独的数据库查询来分别检查我的所有实体

目前使用的Ef核心版本:5.0.100-preview

这只是一个例子。这至少需要10个实体,如果单独为每个实体执行,将导致高数据库流量


有什么想法吗?

如果您只需要每个记录集中第一个版本的标题,您的查询可以简化,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();