【发布时间】:2017-02-23 10:46:27
【问题描述】:
我目前正在asp.net 中开发一个Web 应用程序。在某些 api 调用中,有必要将 ListA 与 ListB 的 ListB 进行比较,以确定 ListA 是否具有 ListB 中任何 List 的相同元素。换句话说:如果 ListA 包含在 ListB 中。
使用 EF-Code-First db 的 Linq 查询这两个集合。 ListB 要么有一个匹配的 List,要么没有,永远不会超过一个。在最坏的情况下,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 调用)想要提供正确的曲线对象。为了识别正确的对象,提供了一个过滤器(ListA)(实际上是一个曲线对象) 现在需要将过滤器 (ListA) 与结果中的曲线列表 (ListB) 进行比较 比较曲线的唯一方法是比较两者都有的点。 (所以事实上比较列表) 曲线大约有 1 - 50 个点。 结果可以有大约 500.000.000 条曲线
这里可以通过 Object-Identity 进行比较,因为所有的 Objects(甚至是过滤器)都会从 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 -
你需要使用内连接,但不了解结构,很难建议。
-
这部分可以澄清一下:“最坏情况 ListB 有数百万个元素” - 数百万个元素还是数百万个列表?
-
这是一个有趣的问题,但由于“百万”这个词,我也会考虑纯 SQL 解决方案或部分 SQL 解决方案。
-
我认为您应该使用纯 SQL 来解决这个问题,通过适当的索引,应该能够在这么多数据上提供充足的性能。它可以像单个 JOIN 一样简单,结合 COUNT 以确保所有元素都匹配(或任何其他用于集合相等的 SQL 咒语)。
标签: c# entity-framework linq bigdata