使用Group by时无法转换LINQ表达式
我有一个Asp.net核心web API,它使用EF core DB first方法。我的SQL server数据库中有以下表格使用Group by时无法转换LINQ表达式,linq,asp.net-core,entity-framework-core,Linq,Asp.net Core,Entity Framework Core,我有一个Asp.net核心web API,它使用EF core DB first方法。我的SQL server数据库中有以下表格 应用程序表-包含应用程序列表 角色表-包含角色列表(用户、管理员、超级管理员等) 用户表-包含用户列表 用户角色表-包含用户和角色表之间的映射 功能表-包含功能列表(主页、用户管理等) 角色特征表-包含特征和角色表之间的映射 我正在尝试获取给定UserId和appId的角色名和特性列表 以下是我到目前为止的Linq查询: RoleDto role = f
- 应用程序表-包含应用程序列表
- 角色表-包含角色列表(用户、管理员、超级管理员等)
- 用户表-包含用户列表
- 用户角色表-包含用户和角色表之间的映射
- 功能表-包含功能列表(主页、用户管理等)
- 角色特征表-包含特征和角色表之间的映射
RoleDto role =
from a in ctx.Application.Where(x => x.ApplicationId == appId)
from r in ctx.Role.Where(x => x.ApplicationId == a.ApplicationId)
from ur in ctx.UserRole.Where(x => x.UserId == userId && x.RoleId == r.RoleId)
from rf in ctx.RoleFeature.Where(x => x.RoleId == ur.RoleId)
from f in ctx.Feature.Where(x => x.FeatureId == rf.FeatureId).Where(x => x.IsActive)
group new { r.RoleName, f.FeatureId } by ur.RoleId into g
select new RoleDto
{
Name = g.Select(x => x.RoleName).FirstOrDefault(),
FeatureIds = g.Select(x => x.FeatureId).ToList()
}.AsNoTracking()
但是,我收到一个错误,表示无法转换LINQ表达式。问题在于“groupby”查询的select部分中的FirstOrDefault()
您可能正在使用高于2.1的ef核心版本,并且在处理groupby查询时有一些更改。您应该查看以下链接:
在版本2.1之前,在EF Core中,GroupBy LINQ操作符始终
在内存中进行评估。我们现在支持将其转换为SQL组
在最常见的情况下,按条款
因此,应该将查询转换为SQL GROUP BY,但无法转换FirstOrDefault()等方法。作为一种快速解决方案,您可以使用Max()、Min()或DB中支持的其他聚合函数更改FirstOrDefault()
应用程序
。您可以直接选择Role
作为开始-用户
有多个角色
,那么您将尝试使用第一个角色。当您选择Role
as时,应该这样做-RoleName
和FeatureId
的列表,然后在客户端进行分组-我试着注释掉语句
Name=g.Select(x=>x.Name).FirstOrDefault(),
。我仍然得到同样的错误。我正在使用.net core 3.1 FeatureId呢?你能不能也试着评论一下?我猜问题出在GroupBy上,因为它最近在EfCore中发生了根本性的变化。我认为您只能在groupBy的select部分使用聚合函数。请参阅,并使用AsEnumerable
和ToList
。
from r in dbCtx.Role.Where(x => x.ApplicationId == appId)
from r in ctx.Role.Where(x => x.ApplicationId == a.ApplicationId).Take(1)
var query =
from r in dbCtx.Role.Where(x => x.ApplicationId == appId).Take(1)
from ur in dbCtx.UserRole.Where(x => x.UserId == userId && x.RoleId == r.RoleId)
from rf in dbCtx.RoleFeature.Where(x => x.RoleId == ur.RoleId && x.Feature.IsActive)
select new
{
RoleName = rf.Role.RoleName,
FeatureId = rf.FeatureId
};
var roleDto = query.AsNoTracking()
.AsEnumerable()
.GroupBy(p => p.RoleName)
.Select(g => new RoleDto
{
Name = g.Key,
FeatureIds = g.Select(p => p.FeatureId).ToList()
})
.FirstOrDefault();