我试图让我的实体只有一些孩子(一个),但我的要求非常慢。
我的课程是:
我想过滤我的电路,从每个电路的第一个etape获得一些地理位置,并获得所有匹配我的滤波器但仅与我的电路的第一个etape匹配的电路实体。 (所以我的过滤电路与numEtape == 1
)的etape。
我只想要第一个etape,因为它可以是每个电路10,20,30 .. etapes,所以为了减少我的查询的迟到。
这是我现在的查询,它可能非常慢,仅需要20 000个电路进行过滤。 (但是使用X etape,etape有Y问题..)
var x = db.circuit.Include("etape").Include("etape.question")
.Where(
c => c.etape.Count() >= 2 &&
c.enabled &&
!circuitsAfficher.Contains(c.id) &&
(
c.etape.Where(e => e.numEtape == 1).FirstOrDefault().posLat > xbottom &&
c.etape.Where(e => e.numEtape == 1).FirstOrDefault().posLat < xtop
) &&
(
c.etape.Where(e => e.numEtape == 1).FirstOrDefault().posLong < yright &&
c.etape.Where(e => e.numEtape == 1).FirstOrDefault().posLong > yleft
)
)
.Select(p => new
{
circuit = p,
etape = p.etape.Where(c => c.numEtape == 1)
}).ToList();
编辑:感谢@Ivan Stoev工作的新代码
listFiltred = db.circuit.AsNoTracking().Where(
c => c.etape.Count() >= 2 &&
c.enabled &&
!circuitsAfficher.Contains(c.id) &&
c.etape.Any(e => e.numEtape == 1 &&
e.posLat > Xbottom && e.posLat < Xtop &&
e.posLong < yright && e.posLong > Yleft))
.Select(p => new CircuitWithEtape
{
circ = p,
firstetape = p.etape.Where(c => c.numEtape == 1).FirstOrDefault()
}).ToList();
CircuitWithEtape类:
public class CircuitWithEtape
{
public circuit circ { get; set; }
public etape firstetape { get; set; }
}
此时我有一个电路清单,所有的etape与他的第一个etape(firstetape)配对。
答案 0 :(得分:1)
您可以使用基于Any
的单一条件替换所有基于c.etape.Where(e => e.numEtape == 1).FirstOrDefault()
的条件(我怀疑每个条件生成一个子查询):
.Where(
c => c.etape.Count() >= 2 &&
c.enabled &&
!circuitsAfficher.Contains(c.id) &&
c.etape.Any(e => e.numEtape == 1 &&
e.posLat > xbottom && e.posLat < xtop &&
e.posLong < yright && e.posLong > yleft)
)
应在主查询中生成单个EXISTS (subquery)
条件。
编辑:查看最终查询,以下情况可能会更好:
listFiltred =
(from c in db.circuit.AsNoTracking()
.Where(c => c.etape.Count() >= 2 &&
c.enabled &&
!circuitsAfficher.Contains(c.id))
from e in c.etape
.Where(e => e.numEtape == 1 &&
e.posLat > Xbottom && e.posLat < Xtop &&
e.posLong < yright && e.posLong > Yleft)
select new CircuitWithEtape
{
circ = c,
firstetape = e
}).ToList();