EF 多对多选择交叉点

本文关键字:交叉点 选择 EF | 更新日期: 2023-09-27 18:37:01

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

List<string> intersectTags = new List<string>();
foreach (object i in ef.objects.Where(o => o.Attributes.All(attribute =>
intersectTags.Contains(attribute.AttributeNK))))

更新:还需要获取 ef.对象具有比 intersectTags 更多的标记。筛选 intersectTags 是 Object.Properties 的子集的实例。

EF 多对多选择交叉点

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

如果要匹配 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))))
我不知道

我是否理解得很好,如果是这样,我可以用普通SQL给出解决方案。您必须查找包含其中一个请求标签的所有记录,然后按 productId 对它们进行分组,并使用以下子句 HAVE 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类,您可以在此处找到它:

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

保罗