首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >由于单个查询中有多个查询,c# linq语法较慢

由于单个查询中有多个查询,c# linq语法较慢
EN

Stack Overflow用户
提问于 2014-01-17 07:16:31
回答 3查看 744关注 0票数 1

我想知道是否有更好、更有效的方法来重新编码下面的linq语法,以使查询运行得更快,即通过对数据库的一次调用。我的数据库位于远程位置,这导致速度非常慢:

代码语言:javascript
运行
复制
    var query = (from ticket in dataClassesDataContext.Tickets.Where(TicketsToShow.And(SearchVals))
                                select new 
                                {
                                    Priority = ticket.TicketPriority.TicketPriorityName,
                                    Ticket = string.Format(TicketFormat, ticket.TicketID),
                                    AssetId = ticket.Asset.Serial,
                                    OpenDate = ticket.CheckedInDate,
                                    OpenFor = CalculateOpenDaysAndHours(ticket.CheckedInDate, ticket.ClosedDate),
                                    Account = ticket.Account.Customer.Name,
                                    Description = ticket.Description.Replace("\n", ", "),
                                    Status = ticket.TicketStatus.TicketStatusName,
                                    Closed = ticket.ClosedDate,
  THIS IS THE CAUSE ====>>>         Amount = GetOutstandingBalanceForTicket(ticket.TicketID),
                                    Paid = ticket.Paid,
                                    Warranty = ticket.WarrantyRepair,
                                    AssetLocation = GetAssetLocationNameFromID(ticket.Asset.LocationID, AssLocNames)
                                }).Skip(totalToDisplay * page).Take(totalToDisplay);

                    if (SortOrder.ToLower().Contains("Asc".ToLower()))
                    {
                        query = query.OrderBy(p => p.OpenDate);
                    }
                    else
                    {
                        query = query.OrderByDescending(p => p.OpenDate);
                    }//ENDIF

性能不佳的主要原因是下面的函数GetOutstandingBalanceForTicket中的代码,该代码计算发票中所有项目的总和,并将其作为字符串中的总数返回:

代码语言:javascript
运行
复制
public static string GetOutstandingBalanceForTicket(int TicketID)
{
    string result = string.Empty;
    decimal total = 0;

    try
    {
        using (DataClassesDataContext dataClassesDataContext = new DataClassesDataContext(cDbConnection.GetConnectionString()))
        {
            var queryCustomerTickets = from ticket in dataClassesDataContext.Tickets
                                       where
                                       (ticket.TicketID == TicketID)
                                       select ticket;

            if (queryCustomerTickets != null)
            {
                foreach (var ticket in queryCustomerTickets)
                {
                    var queryTicketChargeItems = from chargeItem in dataClassesDataContext.ProductChargeItems
                                                 where chargeItem.ChargeID == ticket.ChargeID &&
                                                 chargeItem.Deleted == null
                                                 select chargeItem;

                    foreach (var chargeItem in queryTicketChargeItems)
                    {
                        total += (chargeItem.Qty * chargeItem.Price);
                    }
                }
            }
        }
    }
    catch (Exception ex)
    {

    }

    return total.ToString("0.##");
}

提前谢谢你。

EN

回答 3

Stack Overflow用户

发布于 2014-01-17 07:33:53

正如您所指出的,这段代码相当慢,因为每个票证都需要一个查询。

要消除多个查询的需要,您应该考虑在ticketsToShow和tickets实体(在ticketid上)之间应用内连接,使用groupby提供每个票证的费用总和。

这在对LINQ: Using INNER JOIN, Group and SUM的回答中得到了很好的说明

票数 2
EN

Stack Overflow用户

发布于 2014-01-17 07:40:25

理想情况下,您可能会更多地将其视为一次加载所有类型的设置。然而,我不认为linq2sql支持这一点(我知道EF支持)。不过,您可以做的一件事是避免嵌套查询。由于您已经有权访问ticket表,因此您可能应该从select语句中对其发出Sum()。我很难验证这是否是一种改进,所以如果你愿意的话,这段代码是一种即时的。

代码语言:javascript
运行
复制
 //(from ticket in dataClassesDataContext.Tickets.Where(TicketsToShow.And(SearchVals))
 (from ticket in dataClassesDataContext.Tickets

//如果可能,您可以在此处进行紧急加载(并非完全必需)//。包含仅用作示例的EF方法/*.Include(t => t.TicketPriority)//紧急加载必需的实体.Include(t => t.Asset)//紧急加载必需的实体.Include(t => t.Account.Customer)//紧急加载必需的实体.Include(t => t.TicketStatus)//紧急加载必需的实体.Include(t => t.ProductChargeItems)//紧急加载必需的实体*/

代码语言:javascript
运行
复制
 .Where(TicketsToShow.And(SearchVals))
   select new 
   {
       Priority = ticket.TicketPriority.TicketPriorityName,
       Ticket = string.Format(TicketFormat, ticket.TicketID),
       AssetId = ticket.Asset.Serial,
       OpenDate = ticket.CheckedInDate,
       OpenFor = CalculateOpenDaysAndHours(ticket.CheckedInDate, ticket.ClosedDate),
       Account = ticket.Account.Customer.Name,
       Description = ticket.Description.Replace("\n", ", "),
       Status = ticket.TicketStatus.TicketStatusName,
       Closed = ticket.ClosedDate,
       //Use Sum and the foreign relation instead of a nested query
       Amount = ticket.ProductChargeItems.Where(pci => pci.Deleted == null).Sum(pci => pci.Qty * pci.Price),
       Paid = ticket.Paid,
       Warranty = ticket.WarrantyRepair,
       AssetLocation = GetAssetLocationNameFromID(ticket.Asset.LocationID, AssLocNames)
   }).Skip(totalToDisplay * page).Take(totalToDisplay);

   if (SortOrder.ToLower().Contains("Asc".ToLower()))
   {
       query = query.OrderBy(p => p.OpenDate);
   }
   else
   {
       query = query.OrderByDescending(p => p.OpenDate);
   }
票数 0
EN

Stack Overflow用户

发布于 2014-01-17 07:43:17

我认为,您可以使这个查询更简单。有人是这样想的:

代码语言:javascript
运行
复制
public static string GetOutstandingBalanceForTicket(DataClassesDataContext context, int TicketID)
{
    decimal total = 0;

    var total = (from ticket in context.Tickets
                 join chargeItem from context.ProductChargeItems on chargeItem.ChargeID == ticket.ChargeID
                 where (ticket.TicketID == TicketID && chargeItem.Deleted == null)
                 select chargeItem).Sum(chargeItem => chargeItem.Qty * chargeItem.Price);


    return total.ToString("0.##");
}
/*...*/
Amount = GetOutstandingBalanceForTicket(dataClassesDataContext, ticket.TicketID),

现在,您可以在查询中内联此方法。

它可能包含语法错误,因为我是用记事本写的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21174898

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档