我写了以下代码:
//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
的列表。
我的代码有效,但我认为它不是很有效。有关使其清洁的任何提示吗?
答案 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倍的速度。