【发布时间】:2021-12-25 19:13:02
【问题描述】:
T-SQL 版本的查询
让我们用一些数据建立一个简单的表格:
DROP TABLE IF EXISTS #OrdersTable
CREATE TABLE #OrdersTable
(
Id int,
Custid int
);
INSERT INTO #OrdersTable (Id, Custid) VALUES (1, 71);
INSERT INTO #OrdersTable (Id, Custid) VALUES (2, 71);
INSERT INTO #OrdersTable (Id, Custid) VALUES (3, 71);
INSERT INTO #OrdersTable (Id, Custid) VALUES (4, 72);
INSERT INTO #OrdersTable (Id, Custid) VALUES (5, 72);
INSERT INTO #OrdersTable (Id, Custid) VALUES (6, 72);
INSERT INTO #OrdersTable (Id, Custid) VALUES (7, 73);
INSERT INTO #OrdersTable (Id, Custid) VALUES (8, 74);
INSERT INTO #OrdersTable (Id, Custid) VALUES (9, 74);
在这种情况下,客户 71 和 72 各有 3 个订单。客户 73 有 1 个订单。客户 74 有 2 个订单。
假设我们想了解订单数量最多的客户。
以下查询:
SELECT TOP (1) WITH TIES Custid
FROM #OrdersTable
GROUP BY Custid
ORDER BY COUNT(*) DESC;
结果如下:
Custid
-----------
71
72
(2 rows affected)
到 EF Core 的朴素转换
给定以下类:
public class Order
{
public int Id { get; set; }
public int Custid { get; set; }
}
以及以下数据:
var OrdersTable = new List<Order>()
{
new Order(){ Id = 1, Custid = 71},
new Order(){ Id = 2, Custid = 71},
new Order(){ Id = 3, Custid = 71},
new Order(){ Id = 4, Custid = 72},
new Order(){ Id = 5, Custid = 72},
new Order(){ Id = 6, Custid = 72},
new Order(){ Id = 7, Custid = 73},
new Order(){ Id = 8, Custid = 74},
new Order(){ Id = 9, Custid = 74},
};
这是查询到 EF Core 的简单转换:
var n = OrdersTable.GroupBy(order => order.Custid).Select(grouping => grouping.Count()).Max();
var custids = OrdersTable.GroupBy(order => order.Custid).Where(grouping => grouping.Count() == n).Select(grouping => grouping.Key);
使用以下方式显示数据:
foreach (var custid in custids)
Console.WriteLine(custid);
我们得到:
71
72
问题
让我们将 T-SQL 和 EF Core 版本并排放置。 T-SQL:
SELECT TOP (1) WITH TIES Custid
FROM #OrdersTable
GROUP BY Custid
ORDER BY COUNT(*) DESC;
EF 核心:
var n = OrdersTable.GroupBy(order => order.Custid).Select(grouping => grouping.Count()).Max();
var custids = OrdersTable.GroupBy(order => order.Custid).Where(grouping => grouping.Count() == n).Select(grouping => grouping.Key);
我的问题是,有没有更有效的方法在 EF Core 中实现这个查询?
完整程序
演示上述查询的完整 C# 控制台程序:
using System;
using System.Collections.Generic;
using System.Linq;
namespace EfCoreTop1Ties
{
public class Order
{
public int Id { get; set; }
public int Custid { get; set; }
}
internal class Program
{
static void Main(string[] args)
{
var OrdersTable = new List<Order>()
{
new Order(){ Id = 1, Custid = 71},
new Order(){ Id = 2, Custid = 71},
new Order(){ Id = 3, Custid = 71},
new Order(){ Id = 4, Custid = 72},
new Order(){ Id = 5, Custid = 72},
new Order(){ Id = 6, Custid = 72},
new Order(){ Id = 7, Custid = 73},
new Order(){ Id = 8, Custid = 74},
new Order(){ Id = 9, Custid = 74},
};
var n = OrdersTable.GroupBy(order => order.Custid).Select(grouping => grouping.Count()).Max();
var custids = OrdersTable.GroupBy(order => order.Custid).Where(grouping => grouping.Count() == n).Select(grouping => grouping.Key);
foreach (var custid in custids)
Console.WriteLine(custid);
}
}
}
【问题讨论】:
-
可能值得指出的是,EF 核心可以使用原始 SQL 作为实体集的源,甚至可以在它们之上编写更多查询
标签: c# entity-framework tsql entity-framework-core