Linq语句需要优化

时间:2010-12-14 17:10:03

标签: c# linq linq-to-sql lambda

我写了以下代码:

//get the user from the DB
var tmpuser = _db.aspnet_Users.First(q => q.UserName == user.Identity.Name);

//list the direct connections to Verbond
List<Verbond> verb1 = tmpuser.UsersVerbondens
                             .Where(q => q.Schooljaar.Sch_Schooljaar == schooljaarparam)
                             .Select(q => q.Verbond)
                             .ToList();

//list the connected Facturatieverbonden
List<FacturatieVerbonden> verb2 = tmpuser.UsersFacturatieVerbondens
                                         .Where(q => q.Schooljaar.Sch_Schooljaar == schooljaarparam)
                                         .Select(q => q.FacturatieVerbonden)
                                         .ToList();

//loop through the facturatieverbonden and add their verbonds to the first list
foreach (FacturatieVerbonden v in verb2) {
    verb1.AddRange(v.Verbonds);
}

//make a distinct list
List<Verbond> test = verb1.Distinct().ToList();

因此,用户可以连接到0个或更多facturatieverbonden,也可以连接到verbond

facturatieverbonden可以有一个或多个verbond

我需要的是用户直接或间接通过verbond连接到的所有facturatieverbonden的列表。

我的代码有效,但我认为它不是很有效。有关使其清洁的任何提示吗?

2 个答案:

答案 0 :(得分:5)

你的查询不是很LINQy。这是一个潜在的改进:

           //list the direct connections to Verbond 
var test = (from q in tmpuser.UsersVerbondens
            where q.Schooljaar.Sch_Schooljaar == schooljaarparam
            select q.Verbond)
           //return distinct values
           .Union
           //list the connected Facturatieverbonden 
           (from q in tmpuser.UsersFacturatieVerbondens
            where q.Schooljaar.Sch_Schooljaar == schooljaarparam
            from v in q.FacturatieVerbonden.Verbonds
            select v)
           //return a List
           .ToList();

通过使ToList完成它的最后一件事,整个计算可以在数据库中完成,避免所有中间列表。

答案 1 :(得分:0)

您的性能问题就在这里。每个AddRange调用都将枚举v.Verbonds,每个都将是一个数据库往返。

//loop through the facturatieverbonden and add their verbonds to the first list 
foreach (FacturatieVerbonden v in verb2) { 
    verb1.AddRange(v.Verbonds); 
} 

修复它:

//query the connected Facturatieverbonden 
IQueryable<FacturatieVerbonden> verbQuery2 = tmpuser.UsersFacturatieVerbondens 
  .Where(q => q.Schooljaar.Sch_Schooljaar == schooljaarparam) 
  .Select(q => q.FacturatieVerbonden);

verb1.AddRange(verbQuery2.SelectMany(fv => fv.Verbonds));

仍然有足够的空间来收紧表现,但至少可以解决这个问题。你可以很容易地观察到10倍的速度。