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