Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#LINQ选择项目过滤_C#_Linq_Self Join - Fatal编程技术网

C#LINQ选择项目过滤

C#LINQ选择项目过滤,c#,linq,self-join,C#,Linq,Self Join,我使用的是C#3.5,我有一个IList,其中MyItemLinkProperty表示一个项目与其属性(一个或多个)之间的链接。它有ItemId,PropertyId,PropertyValue。在这个列表中,ItemId可以出现很多次,因为一个项目可以有很多属性、颜色、大小等(这是一个性能相关的问题,我有这种类型的列表,但没有映射到项目实体) 现在我需要找到所有具有属性A和属性B的项目。例如“红色”和“小”。这将为我提供同时具有这两个属性的ItemID1001 在伪代码中,我想我在追求“给我属

我使用的是C#3.5,我有一个
IList
,其中
MyItemLinkProperty
表示一个项目与其属性(一个或多个)之间的链接。它有
ItemId
PropertyId
PropertyValue
。在这个列表中,
ItemId
可以出现很多次,因为一个项目可以有很多属性、颜色、大小等(这是一个性能相关的问题,我有这种类型的列表,但没有映射到项目实体)

现在我需要找到所有具有属性A和属性B的项目。例如“红色”和“小”。这将为我提供同时具有这两个属性的
ItemID
1001

在伪代码中,我想我在追求“给我属性id为1或2且项目id相同的项目”。然后我知道一个get项同时具有这两个属性

我想linq查询就可以了。但是没有让它工作,并且卡住了。也许我在这里阻塞了我的思维,想得太多,太复杂了


关于这个问题的最佳解决方案有什么建议吗

您需要按
ItemID
分组,然后检查每个组是否包含所有值,如下所示:

var smallRedIds = allItems
    .GroupBy(i => i.ItemID)
    .Where(g => g.Any(x => x.PropId == 1 && x.PropValue == "Red")
             && g.Any(x => x.PropId == 2 && x.PropValue == "Small"))
    .Select(g => g.Key);

这将生成同时具有“small”和“red”属性的所有项目ID的枚举。

您可以定义所需属性的列表,例如:

var desiredProperties = new[]{ "Red", "Small" };
然后您可以使用
可枚举。所有
都包含

var allMatchingItemProperties = allItemProperties
    .Where(ip => desiredProperties.All(dp => ip.Properties.Contains(dp)));

我遇到过类似的问题,并使用JOIN解决了它。然后可以轻松地使用它生成动态查询:

int[] propertyIds = new []{1,2,3,4};
var query = dc.ItemProperties.Where(i=> i.PropId == propertyIds[0]);

for (int i = 1; i < catsGroups.Length;i++)
{
    query = query.Join(dc.ItemProperties.Where(i=> i.PropId == propertyIds[i]), x => x.IDItem, x => x.IDItem,(x, y) => x);
}
return input;
int[]propertyIds=new[]{1,2,3,4};
var query=dc.ItemProperties.Where(i=>i.PropId==propertyIds[0]);
对于(int i=1;ii.PropId==propertyIds[i]),x=>x.IDItem,x=>x.IDItem,(x,y=>x);
}
返回输入;

这样做的一个优点是可以投影所有想要的列(与GroupBy不同),这在某些情况下可能会有所帮助。生成的SQL的性能也非常好(没有像使用
Any
All
这样的子查询)

您尝试了什么?如果你不努力解决问题,人们就不会帮助你……”“如果你不努力解决问题,人们也不会帮助你……”这并不总是真的)我觉得我走错了路,想要“不受污染”的想法,所以我试着问一个问题,如果有人有一些建议的话。很高兴有人这么做了!好好工作,谢谢!今天我学到了一些新东西,包括分组和条件。通过这项工作,我能够提高性能这么多,这是愚蠢的。看起来非常干净,我喜欢。然而,我需要像上面那样匹配多个条件,不确定这个解决方案在这种情况下是否有效。但无论如何,谢谢你,这是一个干净的解决方案,我会记住未来的过滤问题。
int[] propertyIds = new []{1,2,3,4};
var query = dc.ItemProperties.Where(i=> i.PropId == propertyIds[0]);

for (int i = 1; i < catsGroups.Length;i++)
{
    query = query.Join(dc.ItemProperties.Where(i=> i.PropId == propertyIds[i]), x => x.IDItem, x => x.IDItem,(x, y) => x);
}
return input;