2016-06-01 10 views
0

私は自分のエンティティを子(1つ)で取得しようとしていますが、リクエストが非常に遅いです。linqを使用しているEntityFrameworkが遅い

私のクラスは次のとおりです。

  • '回路は': 'エタップ' のリストが含まれてい
  • 'エタップは': '質問' 私は私の回路をフィルタリングする

のリストが含まれ、各回路の最初のエタープからいくつかのジオペソーシズを取得し、私の回路に最初のエタープだけでフィルタに一致する回路エンティティをすべて取得します。 (したがって、numEtape == 1のフィルタリングされた回路のetape)。 私は最初のetapeだけを欲しいです。なぜなら、それは10,20,30 ..回路あたりのetapesになる可能性があるから、私のクエリの潜在性を減らすためです。

これは私の質問です。フィルタリングするのに20 000回の回路で非常に遅くなることがあります。 (しかし、エタップXのエタップ、と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(); 

EDIT:新コード@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)とペアになっています。

+2

'.FirstOrDefault()'と 'カウント()'本当にとして、ここで傷つけるために起こっているの使用効果的に遅延実行をバイパスし、それらを解決するためにデータグラフ全体をロードする!! –

+0

私はCount()の使用を削除できますが、私の回路を最初のetapeの子供の条件でフィルタリングするにはどうしたらいいですか? – Furtiro

+0

'numEtape == 1'は回路ごとに1つのetapeにマッチしますか?それとも、複数のものとマッチすることができますか? –

答えて

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

EDIT:は、最終クエリを見てみると次のようにしても良いかもしれない:

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(); 
+1

それは良いより良いようです!今夜、私のプロジェクトにアクセスできるようになると、私はそれをテストします。私はあなたに連絡をとっていきます、ありがとう! – Furtiro

+0

私の答えはあなたの意見では良いですか?私はFirstOrDefault()を使用します.. – Furtiro

+0

あなたは '選択 '部分を意味しますか?確かに、あなたはそこに好きなものを使うことができます、私の答えは 'Where'句だけを対象としていました。 –

関連する問題