繁体   English   中英

使用分组依据时无法翻译 LINQ 表达式

[英]Unable to translate the LINQ expression while using Group by

我有一个 Asp.net 核心 web API 使用 EF Core DB 优先方法。 我的 SQL 服务器数据库中有以下表格。

  • 应用程序表 - 包含应用程序列表。
  • 角色表 - 包含角色列表(用户、管理员、超级管理员等)
  • 用户表 - 包含用户列表
  • 用户角色表 - 包含用户和角色表之间的映射
  • 功能表 - 包含功能列表(主页、用户管理等)
  • RoleFeature 表 - 包含 Feature 和 Role 表之间的映射

我正在尝试获取给定 UserId 和 appId 的 RoleName 和功能列表。

以下是我到目前为止的 Linq 查询:

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查询方面有一些变化。 您应该查看以下链接:

https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-2.1#linq-groupby-translation

在 2.1 版之前,在 EF Core 中,GroupBy LINQ 运算符将始终在 memory 中进行评估。我们现在支持在大多数常见情况下将其转换为 SQL GROUP BY 子句。

所以查询应该翻译成SQL GROUP BY,但是FirstOrDefault()等方法不能翻译。 作为一种快速解决方案,您可以将 FirstOrDefault() 更改为 Max()、Min() 或数据库中支持的其他聚合函数。

  1. 您不需要 select Application 您可以直接选择Role作为开始 -
from r in dbCtx.Role.Where(x => x.ApplicationId == appId)

这将简化 EF 生成的最终 SQL。 所以查询会更快。

  1. 如果User有多个Role ,那么您将尝试担任第一个角色。 当您选择Role as 时,您应该这样做 -
from r in ctx.Role.Where(x => x.ApplicationId == a.ApplicationId).Take(1)
  1. 最后,您可以获取RoleNameFeatureId的列表,然后在客户端进行分组 -
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();

我有一个 Asp.net 核心 web API 使用 EF Core DB 第一种方法。 我的 SQL 服务器数据库中有以下表格。

  • 应用程序表 - 包含应用程序列表。
  • 角色表 - 包含角色列表(用户、管理员、超级管理员等)
  • 用户表 - 包含用户列表
  • 用户角色表 - 包含用户和角色表之间的映射
  • 功能表 - 包含功能列表(主页、用户管理等)
  • RoleFeature 表 - 包含 Feature 和 Role 表之间的映射

我正在尝试获取给定 UserId 和 appId 的 RoleName 和功能列表。

以下是我到目前为止的 Linq 查询:

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 表达式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM