【问题标题】:Optimizing LINQ Query using Entity Framework使用实体框架优化 LINQ 查询
【发布时间】:2015-04-29 12:47:06
【问题描述】:

我有一个使用实体框架获取产品信息的以下 LINQ 查询

productDetails.Items = (from productDetail in db.ToList()
                            select new prod
                            {
                                ID = productDetail.ID
                            ProdName = productDetail.ProductName,
                                        ...
                                        ...
                                        ...
                                        ...
                            Calaculation1 = GetCalaculation(productDetail.Calc1),
                            Calaculation1 = GetCalaculation(productDetail.Calc2),
                                        ...
                                        ...
                                        ...
                                        ...
                                        Calaculation15 = GetCalaculation(productDetail.Calc3)
                            }
                        ).ToList();

GetCalaculation 方法还使用 LINQ 查询 DB。如果我要获取 100 条记录,查询会很慢。我该如何优化它?

【问题讨论】:

  • 我认为您还需要向我们展示 GetCalaculation()。
  • 因为您正在调用ToList,所以您的查询在内存中运行,并且每个GetCalculation 方法调用都会进行单独的数据库查询。那肯定不会扩展。
  • 简短的回答是不要使用实体框架编写直接查询或使用 db.SQLQuery
  • 这里是 GetCalculation 方法 var dbQuery = (来自 db.Calculations 中的计算 wherecalculation.calc == calc1 选择计算); totalsum = (从 dbQuery 中的 xyz 选择 (Decimal?)xyz.calc).Sum() ?? 0;

标签: c# asp.net-mvc linq linq-to-entities


【解决方案1】:

首先,由于您为每条记录获取 15 个 Calaculation 属性,因此您的 select 结构对我来说似乎有点“小”问题。即使您在数据库中创建一个视图,它也会有 15 个 Joins 到计算表,这对性能非常不利。因此,您应该做的第一件事是检查您的对象结构并确认您确实需要在一个请求中获取所有这些计算。 如果您坚持不能更改您的结构,这里有一些可以显着提高性能的步骤:

  1. 如果表不经常更改,您可以考虑创建包含已计算数据的物化视图(SQL Server 中具有聚集索引的视图)。在这种情况下,查询会非常快,但对表的插入/更新会慢得多。
  2. 不要在查询中使用db.ToList() - 通过这样做,您会将所有表提取到内存中,然后为每个计算发出单独的查询。

  3. 我对这个查询有点困惑:

    var dbQuery = from calculation in db.Calculations 
                  where calculation.calc == calc1 select calculation); 
    var totalsum = (from xyz in dbQuery select (Decimal?)xyz.calc).Sum() ?? 0;
    

您正在获取所有具有calc == calc1 的记录,然后计算它们的总和?计算有多少条记录有calc == calc1,然后乘以calc1,这不是更容易吗

db.Calculations.Count(c=>c.calc == calc1) * calc1;
  1. 如果记录数量有限,将所有计算表连同产品表 (var calcTable = db.Calculations.ToList()) 一起放入内存可能会更便宜,那么 GetCalaculation 将更快地处理内存中的对象。如果您打算这样做,您可以考虑并行或在单独的任务中进行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-25
    • 2014-01-11
    • 1970-01-01
    相关资源
    最近更新 更多