【问题标题】:Linq statements need optimizingLinq 语句需要优化
【发布时间】:2010-12-14 17:10:02
【问题描述】:

我写了以下代码:

//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

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

我的代码有效,但我认为它不是很有效。有什么让它更干净的提示吗?

【问题讨论】:

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


    【解决方案1】:

    您的查询不是很 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 设为最后一件事,整个计算可以在数据库中完成,避免了所有中间列表。

    【讨论】:

    • 好主意但小问题:q.Verbond 和 vf.Verbonds(复数)是不同的类型。
    • David B:这就是用外语编程的问题——很难说什么时候没有意义。我现在有吗?
    【解决方案2】:

    您的性能问题就在这里。每个 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 倍的加速。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-23
      • 1970-01-01
      相关资源
      最近更新 更多