EF多对多选择交叉点

时间:2015-01-11 05:46:02

标签: c# entity-framework-6

我正在尝试使用C#实体框架实现标记系统。我无法获得预期两个或多个标记都存在以返回结果的情况所需的查询。我有多对多的关系(只是FK,DB优先),我试图在所有选定的标签存在时获得一个对象。 Object - LookupTable - 属性。 我将选定的标签解析为列表,然后尝试仅获取此列表中所有标签都存在的对象。它似乎导致了我对“任何”操作符的期望,而不是“全部”。

List<string> intersectTags = new List<string>();

foreach (object i in ef.objects.Where(o => o.Attributes.All(attribute =>
intersectTags.Contains(attribute.AttributeNK))))

更新:还需要获取ef.Object的标签多于intersectTags的实例。过滤其中intersectTags是Object.Attributes的子集的实例。

2 个答案:

答案 0 :(得分:1)

如果您的属性是所选标记的子集,则代码会失败。

如果您想在intersectTags是o.Attributes的子集时匹配,请尝试撤消检查。

不幸的是,Linq to Entity不支持这种语法,我们需要ToList()来加载对象并执行Linq To Objects。

它应该可以工作但是会有性能影响(如果我有更好的解决方案,我会发布更新):

List<string> intersectTags = new List<string>();

foreach (object i in ef.objects.ToList().Where(intersectTags.All(tags =>
o.Attributes.Any(attribute => attribute.AttributeNK == tags))))

答案 1 :(得分:0)

我不知道我是否理解得很好,如果是这样我可以用简单的SQL提供解决方案。您必须查找包含所请求标记之一的所有记录,然后通过productId将它们分组,其中HAVING COUNT子句等于您传递的标记数。

SELECT ProductId FROM ProductTag
WHERE  TagId IN (2,3,4)
GROUP BY ProductId
HAVING COUNT(*) = 3

这是一个演示:

http://sqlfiddle.com/#!3/dd4023/3

对不起,目前我不能在EF中给你一个实现(没有我的Visual Studio),我为LINQ TO SQL做了类似的事情,它使用了PredicateBuilder类,你可以在这里找到它: / p>

http://www.codeproject.com/Articles/36178/How-to-manage-product-options-with-different-price