【问题标题】:Converting a SQL server query to EF Core LINQ将 SQL 服务器查询转换为 EF Core LINQ
【发布时间】:2020-06-14 22:17:52
【问题描述】:

我目前正在尝试将现有 SQL Server 查询转换为 EF Core。目标是获取所有用户并获取他们最新的订单日期时间和最新的支持请求日期时间。我想确保即使用户还没有订单或支持请求,他们也会被退回。如果他们没有下订单,“最新订单日期-时间”一栏应为 NULL。如果他们没有提交支持请求,“最新支持请求日期-时间”列应为 NULL。

输出的列应该是:Id、Name、Email、LatestOrderDateTime、LatestSupportRequestDateTime

这是我的工作 SQL 服务器查询:

SELECT [User].[Id], [User].[Name], [User].[Email], MAX([Order].[DateTime]) as LatestOrderDateTime, MAX([SupportRequest].[DateTime]) as LatestSupportRequestDateTime FROM [User]
LEFT JOIN [Order] on [User].[Id] = [Order].[UserId]
LEFT JOIN [SupportRequest] on [User].[Id] = [SupportRequest].[ConsumerId]
GROUP BY [User].[Id], [User].[Name], [User].[Email]
ORDER BY [User].[Id]

这是我尝试过的,但它没有在服务器上评估:

await this.context.User
    .GroupBy(u => new { u.Id, u.Name, u.Email })
    .Select(g => new
    {
        id = g.Key.Id,
        name = g.Key.Name,
        email = g.Key.Email,
        lastOrderDateTime = g.Max(o => o.Orders.Select(o => o.DateTime)),
        lastSupportRequestDateTime = g.Max(o => o.SupportRequests.Select(s => s.DateTime)),
    })
    .OrderBy(c => c.id)
    .ToListAsync();

我只想将此查询转换为 EF 核心(查询不会在本地进行评估)。

如果你可以在方法语法中做到这一点,那就太好了,但如果没有,我可以用 JetBrains Rider 转换它。

非常感谢您的帮助!

【问题讨论】:

  • 仅供参考,它是查询语法,而不是 lambda 语法。 Lambda 用于查询语法和方法语法,因此名称有点混乱。
  • “我目前正在尝试将现有的 SQL 服务器查询转换为 EF Core”——您的帖子并没有以任何方式显示这一点。到目前为止,您尝试过什么? ;)
  • 好点@TomTom,已修复!
  • 如果我正确地遵循了您的问题,则不会,但 ToListAsync 是在本地评估您的查询的方法。如果您删除该 ToListAsync,则不会在本地对其进行评估。
  • 不对。 ToListAsync 触发评估,但这并不意味着它在本地执行它。如果 context.User 是 ef(core) 那么此时它将生成并发送 sql。

标签: c# sql-server linq entity-framework-core


【解决方案1】:

我只想将此查询转换为 EF 核心(未评估该查询 本地)。

做不到,使用EntityFramework 6.4,不是核心,如果你想要这个。

当前 EntityFramework 中的 SQL 生成(我的意思是当前到veryion 5 的每晚构建)在它可以生成的 SQL 中是极其有限的,再加上看起来完全无知甚至无法接受团队的事实(其中让我想起了 EntityFramework 2 和 3 的时代,直到那个团队在他们的版本 4 中开始认真对待 LINQ)。

如果它告诉您它不能将其生成为 SQL,那么您仅有的 2 个选择是:

  • 使用 EntityFramework 6.4(在 dotnetcore 3.1 中工作)并获取服务器端执行
  • 打开一个错误报告,希望有人知道它,然后要么等到 11 月发布第 5 版,要么 - 一旦它可能得到修复 - 在此之前使用夜间构建。

这不是语法问题。他们停用了对 SQL 的客户端评估,并且他们的 SQL 生成器无法处理很多标准案例。鉴于您不想要第一个(这是我们目前所做的),他们的功能集只是意味着它无法完成。

【讨论】:

  • 谢谢!我现在只使用原始 SQL。我很感激这些信息。
【解决方案2】:

您可以尝试在 Linq 中明确地拼出左连接(左连接语法有点不直观 iirc,因此可能需要做一些事情来整理它)。

您可以在以下位置找到更多信息:

https://docs.microsoft.com/en-us/dotnet/csharp/linq/perform-left-outer-joins

Linq 的设置方式特别要求对象链接,这就是它发生在客户端的原因。我相信您正在尝试做的事情在 EF Core 中有解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 2016-11-25
    相关资源
    最近更新 更多