如何将 SQL 查询转换为 Linq 表达式,以便在 EF Core 6 中使用各种条件进行联接?

问题描述 投票:0回答:3

这是我正在尝试转换的 SQL 查询:

SELECT TOP (10) 
    t1.ProductName, t2.ProductName, 
    COUNT(DISTINCT t1.OrderId) AS num_orders
FROM 
    Reports t1 
JOIN
    Reports t2 ON t1.OrderId = t2.OrderId
               AND t1.ProductId < t2.ProductId
GROUP BY
    t1.ProductName, t2.ProductName
ORDER BY 
    num_orders DESC

正如你所看到的,在“on”中,

orderId
必须相同,而且其中一个的
productId
必须小于另一个。

这是我迄今为止所取得的成就(非常不完整):

var reportData = await (from t1 in this.Context.Reports 
                        join t2 in this.Context.Reports 
                             on t1.OrderIdequals t2.OrderId
                        where t1.ProductId < t2.ProductId
                        into GroupedData
                        orderby GroupedData.Key
                        select new 
                        {
                           GroupedData
                        }).ToListAsync();

如果我在“on”中放置带有“and”的表达式,并且我尝试在单独的“where”中执行此操作,但它仍然不起作用。

而且选择不完整,因为我还没有设法让上述所有代码正常工作,所以不要重视它。

我最接近让它为我工作的时候,我遇到了与此人相同的错误:How can I use Linq expression for Join with GroupBy in EF Core 3.1

这是我用来搜索信息的页面,但它没有显示我要查找的内容: https://learn.microsoft.com/en-us/ef/core/querying/complex-query-operators

我还使用过 Linqer这个 SQL to Linq 存储库,但我无法让它们工作,我是初级 :(

有人可以帮助我或推荐我在哪里寻找信息吗?

c# sql linq ef-core-6.0
3个回答
0
投票

试试这个

           var reportData = (from t1 in Context.Reports
                             join t2 in Context.Reports on t1.OrderId equals t2.OrderId
                             select new { t1 = t1, t2 = t2 }
                 ).Where(x => x.t1.ProductId < x.t2.ProductId)
                  .GroupBy(x => new { t1Id = x.t1.ProductId, t2Id = x.t2.ProductId })
                  .Select(x => new { t1ProductName = x.First().t1.ProductName, x.First().t2.ProductName, num_Orders = x.Select(y => y.t1.OrderId).Distinct().Count()})
                  .OrderByDescending(x => x.num_Orders);

0
投票

试试这个,

var result = (from t1 in Reports
             join t2 in Reports on t1.OrderId equals t2.OrderId
             where t1.ProductId < t2.ProductId
             group new { t1, t2 } by new { t1.ProductName, t2.ProductName } into g
             let numOrders = g.Select(x => x.t1.OrderId).Distinct().Count()
             orderby numOrders descending
             select new
             {
                 ProductName1 = g.Key.ProductName,
                 ProductName2 = g.Key.ProductName2,
                 NumOrders = numOrders
             }).Take(10);

0
投票
// Just an edit to above answer (correcting error)
var result 
= (from t1 in Reports
  join t2 in Reports on t1.OrderId equals t2.OrderId
  Where t1.ProductId < t2.ProductId
  group new { t1, t2} by new { ProductName1 = t1.ProductName, ProductName2 = t2.ProductName} into g
  let numOrders = g.Select( x => x.OrderId).Distinct().Count()
  orderby numOrders descending
  select new
  {
    ProductName1 = g.Key.ProductName1,
    ProductName2 = g.Key.ProductName2,
    NumOrders = numOrders
  })
  .Take(10);
© www.soinside.com 2019 - 2024. All rights reserved.