В настоящее время я работаю над веб-приложением в asp.net. В некоторых api-вызовах необходимо сравнивать ListA с ListB списков, чтобы определить, имеют ли ListA одинаковые элементы любого List в ListB. Другими словами: если ListA включен в ListB.Как эффективно сравнить список?
Обе коллекции запрашиваются у Linq EF-Code-First db. ListB имеет либо один соответствующий список или ни один, не более одного. В худшем случае ListB имеет миллионы элементов, поэтому сравнение должно быть масштабируемым.
Вместо того, чтобы делать вложенные петли foreach, я ищу чистый запрос linq, который позволит db выполнять работу. (Прежде чем я считать несколько индекс столбца)
Чтобы проиллюстрировать структуру:
//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;
}
}
Обновления структуру
Поскольку его база данных EF я буду предоставлять соответствующую структуру объекта. Я не уверен, что мне разрешено публиковать реальный код, поэтому этот пример по-прежнему является общим.
//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) Единственный способ сравнения Кривые - это сравнение очков, которые имеют. (So infact сравнения списков) Кривые имеют около 1 - 50 очков. Результат может быть около 500.000.000 кривых
Здесь можно сравнить Object-Identity, потому что все объекты (даже фильтр) повторно запрашиваются из db.
Я ищу способ реализовать этот механизм, а не как обойти эту ситуацию. (Например, с помощью нескольких индекс столбца (изменяя таблицу))
(для иллюстрации):
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 –