简体   繁体   English

将 SQL 服务器查询转换为 EF Core LINQ

[英]Converting a SQL server query to EF Core LINQ

I am currently trying to convert an existing SQL server query to EF Core.我目前正在尝试将现有的 SQL 服务器查询转换为 EF Core。 The goal is to get all users and get their latest order date-time and latest support request date-time.目标是获取所有用户并获取他们的最新订单日期时间和最新支持请求日期时间。 I want to ensure users are returned even if they don't have an order yet or a support request yet.我想确保即使用户还没有订单或支持请求也能返回。 If they have not placed an order, the column for "latest order date-time" should be NULL.如果他们还没有下订单,“最新订单日期-时间”栏应该是NULL。 If they have not filed a support request, the column for "latest support request date-time" should be NULL.如果他们尚未提交支持请求,则“最新支持请求日期-时间”列应为 NULL。

The outputted columns should be: Id, Name, Email, LatestOrderDateTime, LatestSupportRequestDateTime输出的列应该是:Id、Name、Email、LatestOrderDateTime、LatestSupportRequestDateTime

Here is my working SQL server query:这是我的工作 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]

This is what I've tried, however it does not evaluate on the server:这是我尝试过的,但是它不会在服务器上评估:

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();

I just want to convert this query to EF core (where the query DOES NOT get evaluated locally).我只是想将此查询转换为 EF 核心(查询不会在本地进行评估)。

If you could do it in method syntax, that'd be great, but no worries if not since I can convert it with JetBrains Rider.如果您可以在方法语法中做到这一点,那就太好了,但不用担心,因为我可以使用 JetBrains Rider 进行转换。

Thank you so much for your help!非常感谢你的帮助!

I just want to convert this query to EF core (where the query DOES NOT get evaluated locally).我只是想将此查询转换为 EF 核心(查询不会在本地进行评估)。

Can not be done, use EntityFramework 6.4, not core, if you want this.做不到,用EntityFramework 6.4,不是核心,如果你想要这个。

The SQL generation in current EntityFramework (and I mean current up to the nightly builds of veryion 5) is EXTREMELY Limited in the SQL it can generate, combined with what looks like utter ignorance to even accept that fact from the team (which reminds me of the times of EntityFramework 2 and 3 until that team started being serious about LINQ in their version 4).当前 EntityFramework 中的 SQL 生成(我的意思是当前到veryion 5 的每晚构建)在它可以生成的 SQL 中非常有限,再加上看起来完全无知甚至无法接受团队的这一事实(这让我想起了EntityFramework 2 和 3 的时代,直到该团队开始认真对待其版本 4 中的 LINQ)。

If it tells you it can not generate this as SQL then your only 2 choises are:如果它告诉您它无法将其生成为 SQL,那么您仅有的 2 个选择是:

  • Use EntityFramework 6.4 (which works in dotnetcore 3.1) and get server side execution使用 EntityFramework 6.4(适用于 dotnetcore 3.1)并获得服务器端执行
  • Open a bug report, HOPE someone picks it up and then either wait until November for the release of version 5 OR - once it possibly is fixed - work with nightly builds until then.打开一个错误报告,希望有人捡起它,然后要么等到 11 月发布第 5 版,要么 - 一旦它可能被修复 - 在此之前使用夜间构建。

This is not a syntax issue.这不是语法问题。 They deactivated client evaluation of SQL and their SQL generator is not able to handle a LOT of standard cases.他们停用了 SQL 的客户端评估,并且他们的 SQL 生成器无法处理很多标准情况。 Given you do not want the first (which is what we do at the moment), their feature set just means it can not be done.鉴于您不想要第一个(这是我们目前所做的),他们的功能集只是意味着它无法完成。

You could try to explicitly spell out the left joins in Linq (left join syntax is a bit un-intuitive iirc so it may take some doing to sort it out).您可以尝试在 Linq 中明确拼出左连接(左连接语法有点不直观 iirc,因此可能需要做一些事情来整理它)。

You can find more information at:您可以在以下位置找到更多信息:

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

The way your Linq is set up specifically asks for object linking, which is why it happens client side.您的 Linq 的设置方式专门要求对象链接,这就是它发生在客户端的原因。 I believe what you're trying to do has a solution in EF Core.我相信您尝试做的事情在 EF Core 中有一个解决方案。

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

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