使用实体框架优化LINQ查询

时间:2015-04-29 03:21:56

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

我有一个以下LINQ查询来使用Entity Framework获取产品信息

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查询数据库。如果我提取100条记录,查询速度很慢。我该如何优化呢?

1 个答案:

答案 0 :(得分:0)

首先,由于您为每条记录提取了15个Calaculation属性,因此对我来说选择的结构看起来有点“问题”。即使您在数据库中创建一个视图,它也会有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;
    
  4. 您正在获取具有calc == calc1的所有记录,然后计算它们的总和?计算有多少记录calc == calc1然后将其乘以calc1

    会不会容易得多
    db.Calculations.Count(c=>c.calc == calc1) * calc1;
    
    1. 如果记录数量有限,将所有计算表与Product表(var calcTable = db.Calculations.ToList())一起提取到内存中可能会更便宜,然后GetCalaculation将与更快的内存中对象一起使用。如果您打算这样做,您可以考虑并行或在单独的任务中执行此操作。