私は現在asp.netのWebアプリケーションで作業しています。特定のAPI呼び出しでは、ListAとListBのListBを比較して、ListAにListBのListの要素が同じかどうかを判断する必要があります。言い換えれば、ListAがListBに含まれている場合。リストを効率的に比較するには?
両方のコレクションは、EF-Code-First dbのLinqで照会されます。 ListBには、Listまたはnoneのいずれかに一致するものが1つあります。複数のものは決してありません。最悪の場合ListBには何百万もの要素があるので、比較はスケーラビリティが必要です。
ネストされたforeachループを実行する代わりに、私は純粋なlinqクエリを探しています。これは、dbに作業をさせます。構造を説明するために
(私はマルチカラムインデックスを検討する前に):そのEFデータベースので
//In reality Lists are queried of EF
var ListA = new List<Element>();
var ListB = new List<List<Element>>();
List<Element> solution;
bool flag = false;
foreach (List e1 in ListB) {
foreach(Element e2 in ListA) {
if (e1.Any(e => e.id == e2.id)) flag = true;
else {
flag = false;
break;
}
}
if(flag) {
solution = e1;
break;
}
}
アップデート構造
を私は、関連するオブジェクトの構造を提供します。私は本当のコードを投稿することができるかどうか分からないので、この例はまだ一般的です。
//List B
class Result {
...
public int Id;
public virtual ICollection<Curve> curves;
...
}
class Curve {
...
public int Id;
public virtual Result result;
public int resultId;
public virtual ICollection<Point> points;
...
}
public class Point{
...
public int Id;
...
}
コントローラ(api-call用)は、正しいCurve-Objectを提供したいと考えています。正しいオブジェクトを識別するために、フィルタ(ListA)が提供されています(実際にはカーブオブジェクトです)。 フィルタ(ListA)を結果リスト(ListB)の曲線リストと比較する必要があります。 曲線は両方のポイントを比較することです。 (実際のリスト比較) 曲線には約1〜50点があります。 結果は約500,000,000になります。
すべてのオブジェクト(フィルタさえも)がdbを再クエリするため、Object-Identityで比較することができます。
このような状況を回避する方法ではなく、このメカニズムを実装する方法を探しています。
bool isIn = ListB.Any(x=>x.Count==ListA.Count && ListA.All(y=>x.Contains(y)));
か、あなたが要素をしたい場合
:はこれを試してみてください
class controller {
...
public Response serveRequest(Curve filter) {
foreach(Curve c in db.Result.curves) {
if(compare(filter.points , c.points)) return c;
}
}
}
あなたのコードはコンパイルされません。実際のコードを載せてください。 obs:それは 'var'です – Lucas
内部結合を使用する必要がありますが、構造をよく知らずに、提案するのは難しいです。 – Dexion
関連性はありますが、ここでEFに関する懸念があるため、詐欺ではありません:http://stackoverflow.com/questions/9524681/linq-compare-two-lists –