EF 多对多 select 交集
EF Many to Many select intersection
我正在尝试使用 C# entity framework 实现标记系统。对于 return 结果预期两个或更多标签都存在的情况,我无法获得所需的查询。我有一个多对多的关系(首先是 FK,DB),当所有选定的标签都存在时,我试图获取一个对象。对象 - LookupTable - 属性。
我将选定的标签解析为一个列表,然后尝试仅获取该列表中所有标签都存在的那些对象。它似乎导致了我对 "Any" 运算符的期望,而不是 "All".
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.
子集的实例
不知道我理解的对不对,如果是我可以通俗的给出解决方案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 class,你可以在这里找到它:
http://www.codeproject.com/Articles/36178/How-to-manage-product-options-with-different-price
保罗
如果您的属性是所选标签的子集,您的代码将失败。
如果您希望匹配 intersectTags 是 o.Attributes 的子集,请尝试反转检查。
很遗憾,Linq to Entity 不支持这种语法,我们需要ToList()
加载对象并执行 Linq To Objects。
它应该可以工作,但会影响性能(如果我有更好的解决方案,我会 post 进行更新):
List<string> intersectTags = new List<string>();
foreach (object i in ef.objects.ToList().Where(intersectTags.All(tags =>
o.Attributes.Any(attribute => attribute.AttributeNK == tags))))
我正在尝试使用 C# entity framework 实现标记系统。对于 return 结果预期两个或更多标签都存在的情况,我无法获得所需的查询。我有一个多对多的关系(首先是 FK,DB),当所有选定的标签都存在时,我试图获取一个对象。对象 - LookupTable - 属性。 我将选定的标签解析为一个列表,然后尝试仅获取该列表中所有标签都存在的那些对象。它似乎导致了我对 "Any" 运算符的期望,而不是 "All".
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.
子集的实例不知道我理解的对不对,如果是我可以通俗的给出解决方案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 class,你可以在这里找到它:
http://www.codeproject.com/Articles/36178/How-to-manage-product-options-with-different-price
保罗
如果您的属性是所选标签的子集,您的代码将失败。
如果您希望匹配 intersectTags 是 o.Attributes 的子集,请尝试反转检查。
很遗憾,Linq to Entity 不支持这种语法,我们需要ToList()
加载对象并执行 Linq To Objects。
它应该可以工作,但会影响性能(如果我有更好的解决方案,我会 post 进行更新):
List<string> intersectTags = new List<string>();
foreach (object i in ef.objects.ToList().Where(intersectTags.All(tags =>
o.Attributes.Any(attribute => attribute.AttributeNK == tags))))