LINQ to SQL分割过滤器以获得更好的性能

时间:2011-07-18 09:38:11

标签: c# linq linq-to-sql

我有以下LINQ to SQL查询

var kayitlarFiltreli = from rows in db.TBLP1CARIs
                       orderby rows.ID descending
                       where rows.HESAPADI.ToLower().Contains(filter.ToLower()) ||
                                              (rows.CARITURU == "Bireysel" ?
                                               rows.B_ADSOYAD.ToLower().Contains(filter.ToLower()) :
                                               rows.K_FIRMAADI.ToLower().Contains(filter.ToLower())) ||
                                               rows.ID.ToString().Contains(filter)
                       select rows;

var kayitlarBakiyeli = from rows in kayitlarFiltreli
                       select new
                                   {
                                       HESAPNO = rows.ID,
                                       HESAPADI = rows.HESAPADI,
                                       CARIADI = (rows.CARITURU == "Bireysel" ? rows.B_ADSOYAD : rows.K_FIRMAADI),
                                       Bakiye = get_bakiye(rows.ID, rows.LISTEPARABIRIMI)
                                   };

var kayitlarSon = from rows in kayitlarBakiyeli
                  select new
                            {  rows.HESAPNO,
                               rows.HESAPADI,
                               rows.CARIADI,
                               Bakiye = rows.Bakiye.Contains(".") == true ?
                                        rows.Bakiye.TrimEnd('0').TrimEnd('.') :
                                        rows.Bakiye

                            };

我遇到性能问题我的意思是查询响应至少在15秒之后,当它部署到网站时,使用这些查询填充GridView的页面至少需要5秒。{ {1}}是一个很长的方法,其中包含get_bakiye(p1,p2,..)for和Linq-to-SQL查询。我认为大部分时间花费在foreach上我努力与它已经并且减少了2秒的响应时间,但它仍然很慢。我正在尝试让上述查询更快地运行。

我试过

get_bakiye

其余的都是一样的。 基本上我只是用var kayitlarSirali = from rows in db.TBLP1CARIs orderby rows.ID descending select rows; var kayitlarFiltreli = from rows in kayitlarSirali where rows.HESAPADI.ToLower().Contains(filter.ToLower()) || (rows.CARITURU == "Bireysel" ? rows.B_ADSOYAD.ToLower().Contains(filter.ToLower()) : rows.K_FIRMAADI.ToLower().Contains(filter.ToLower())) || rows.ID.ToString().Contains(filter) select rows; 分隔了过滤部分,我不确定这是否有用。

分离Contains()是否合适我的意思是在查询数据库时使用过滤器,并且一次查询数据库并将结果输入内存中的IQueryable并在其上执行其余操作更好?

您建议您将这些查询更快地运行? 这是where方法,这不是我完全写的东西,但我应该让它表现得更快。

get_bakiye()

2 个答案:

答案 0 :(得分:3)

一般来说,我认为您需要了解导致Linq to Sql对您的数据库执行查询的原因。通常,ToList()First()FirstOrDefault()Single()等扩展方法将导致Linq To Sql对数据库执行命令。与我有关的一条线是:

List<TBLP1DOVIZTANIMLARI> dovizTanimlariTumListe = DAL.DAOdoviztanimlari.SelectAll().ToList();

这似乎是从DAOdoviztanimlari映射到的数据库表中获取每一行。然后在内存中查询结果。

对于调用get_bakiye()

的查询中的每条记录都会发生这种情况

最终(完美世界)你希望get_bakiye()不包含我提到的任何扩展方法并返回IQueryable<string>然后让Linq to SQL来决定它如何优化和执行SQL。

答案 1 :(得分:1)

首先对数据库进行概要分析,并查看生成的查询执行的时间以及执行的频率。

如果分析的结果显示您正在对数据库执行相同的查询,或者查询执行时间太长,您应该考虑将值加载到内存中并从那里访问它们。或者甚至考虑编译查询作为替代方案,如果这是合理的。

我之前遇到过类似的问题,我通过创建一个单独的类来解决这个问题,该类处理我需要加载到集合中的值并在必要时更新值。