【问题标题】:How i can combine these Linq query and how improve query speed我如何结合这些 Linq 查询以及如何提高查询速度
【发布时间】:2018-07-13 01:50:30
【问题描述】:

我有这个 SQL 脚本,我需要将其转换为 Linq 以与 EF Core 一起使用:

SELECT  
    A.*, B.*
FROM
    [Orders] AS A
JOIN
    (SELECT TOP 1 WITH TIES *
     FROM [OrderMeta]
     ORDER BY ROW_NUMBER() OVER (PARTITION BY OrderId ORDER BY PostDate DESC)
    ) AS B ON (b.OrderId = A.OrderId)

这是我将其转换为的内容:

public async Task<List<GetAllOrdersResult>> AdminGetOrderList()
        {
            using (var db = new SoulDrawContext())
            {
                var query = from A in db.Orders
                            join B in db.OrderMeta
                            on A.OrderId equals B.OrderId
                            select new GetAllOrdersResult
                            {
                                OrderId = A.OrderId,
                                UserId = A.UserId,
                                OrderDate = A.OrderDate.ToLocalTime().ToString("yyyy-MM-dd"),
                                Currency = A.Currency,
                                Amount = A.Amount,
                                PaymentMethod = A.PaymentMethod,
                                ShipTo = A.ShipTo,
                                Status = B.Status,
                                PostDate = B.PostDate.ToLocalTime().ToString("yyyy-MM-dd hh:mm"),
                                RefOrderId = A.RefOrderId
                            };
                var query1 = from a in query
                             group a by a.OrderId
                             into g
                             orderby g.FirstOrDefault().PostDate
                             select new GetAllOrdersResult
                             {
                                 OrderId = g.FirstOrDefault().OrderId,
                                 UserId = g.FirstOrDefault().UserId,
                                 OrderDate = g.FirstOrDefault().OrderDate,
                                 Currency = g.FirstOrDefault().Currency,
                                 Amount = g.FirstOrDefault().Amount,
                                 PaymentMethod = g.FirstOrDefault().PaymentMethod,
                                 ShipTo = g.FirstOrDefault().ShipTo,
                                 Status = g.FirstOrDefault().Status,
                                 PostDate = g.FirstOrDefault().PostDate,
                                 RefOrderId = g.FirstOrDefault().RefOrderId
                             };
                return await query1.ToListAsync();
            }
        }

问题:

在 SSMS 中运行的 SQL 脚本运行良好,查询大约需要 32 毫秒才能完成,但 EF 内核的 linq 查询大约需要 9600 毫秒。

order表大约有2000条记录,ordermeta表有60000条记录。

待办事项

  1. 如何正确地将 SQL 脚本转换为 Linq? (或结合 2 个 linq 查询?)

  2. 如何提高查询速度?

【问题讨论】:

  • 你是用分区来分页的吗?
  • 函数 FirstOrDefault() 不返回 iqueryable。这意味着每个g.FirstOrDefault() 都会运行一个单独的查询。
  • 它不用于分页,ordermeta 表正在记录订单状态,例如:已付款、已发货、退货等。我正在尝试构建一个订单列表,每个订单都包含来自 ordermeta 的最新更新。 sql 脚本工作正常,但 linq 一个不行,我猜我转换的 linq 是错误的?
  • 在您的选择中使用 FirstOrDefault 会使 ef 在每次调用时运行整个 query 查询。看看这个:docs.microsoft.com/en-us/ef/core/what-is-new/….
  • SO 并不是一个真正询问如何使 工作代码 运行得更快的网站。也许在代码审查 Stack Exchange 网站上询问?

标签: c# linq entity-framework-core


【解决方案1】:

试试这个希望它能解决你的问题

 public async Task<List<GetAllOrdersResult>> AdminGetOrderList()
            {
                using (var db = new SoulDrawContext())
                {
                                  var query = from A in db.Orders group A by A.OrderId into g 
                                    join B in db.OrderMeta
                                    on g.FirstOrDefault().OrderId equals B.OrderId
                                    select new GetAllOrdersResult
                                    {
                                        OrderId = g.FirstOrDefault().OrderId,
                                        UserId = g.FirstOrDefault().UserId,
                                        OrderDate = g.FirstOrDefault().OrderDate.ToLocalTime().ToString("yyyy-MM-dd"),
                                        Currency = g.FirstOrDefault().Currency,
                                        Amount = g.FirstOrDefault().Amount,
                                        PaymentMethod = g.FirstOrDefault().PaymentMethod,
                                        ShipTo = g.FirstOrDefault().ShipTo,
                                        Status = B.Status,//now your B in scope so you can use Directly
                                        PostDate = B.PostDate.ToLocalTime().ToString("yyyy-MM-dd hh:mm"),
                                        RefOrderId = g.FirstOrDefault().RefOrderId
                                    };
                         query.OrderBy(B.PostDate);
                        return await query.ToListAsync();
                    }
           }

【讨论】:

  • .OrderBy(B.PostDate);不起作用,OrderBy 不能放在这里。
  • 谢谢@CoolJK 它现在可以工作了,但是查询速度几乎一样,不是更快T_T
  • 也许运行原始 sql 比 linq 更好?
  • 在同一个查询中有很多.FirstOrDefault()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-09
  • 2021-04-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多