C# 选择具有所有标签的产品
我使用的是C#和实体框架。我有一个包含我的产品的Products表(C# 选择具有所有标签的产品,c#,linq,entity-framework,C#,Linq,Entity Framework,我使用的是C#和实体框架。我有一个包含我的产品的Products表(Id,Name),一个包含所有可用标记的Tags表(Id,Name),以及一个用于为产品分配标记的ProductTags表(Id,ProductId,TagId)。 用户可以指定他想要查看具有多个标记的产品(Int[]selectedtagds)。 问题是:如何获取所有产品,其中每个产品都有用户指定的所有标签 现在我使用这个查询 `var reault = Context.Products
Id,Name
),一个包含所有可用标记的Tags表(Id,Name
),以及一个用于为产品分配标记的ProductTags表(Id,ProductId,TagId
)。
用户可以指定他想要查看具有多个标记的产品(Int[]selectedtagds
)。
问题是:如何获取所有产品,其中每个产品都有用户指定的所有标签
现在我使用这个查询
`var reault = Context.Products
.Where(x => SelectedTagIds.All(y =>
(x.ProductTags.Select(z => z.TagId))
.Contains(y)));`
我想知道这是一种正确的方法还是有更好/更快的方法?您可以使用intersect,然后检查两者的长度,确保intersected的计数与搜索标记的计数相同,这意味着所有搜索标记都存在于ProductTags集合中
var result =
products.Where(
x => x.ProductTags.Intersect(searchTags).Count() == searchTags.Length);
但是,您需要运行性能分析,这对您更有效。但正如Oren所评论的,您是否真的存在性能问题?因为这两个集合很可能都很小,所以不会造成瓶颈
编辑:刚刚检查了intersect的性能,它比使用.All with.Contains慢
在我的机器上执行,创建1000个结果查询,并使用ToList()对1000个产品(带有2个搜索标记)进行枚举,可获得以下性能:
searchTags.All(搜索=>x.ProductTags.Contains(搜索))
=202ms
!searchTags.Exception(x.ProductTags).Any()
=339ms
x.ProductTags.Intersect(searchTags).Count()==searchTags.Length
=389ms
如果您确实需要提高性能,您可以对ProductTags和SelectedTagDS使用HashSet
编辑2:使用哈希集比较
使用hashset运行比较,并获得以下输出:创建1000个查询对象,并使用ToList()执行到列表中,得到以下结果:
使用列表
Creating Events took 6ms
Number of Tags = 3000
Number of Products = 1003
Average Number of Tags per Products = 100
Number of Search Tags = 10
.All.Contains = 5379ms - Found 51
.Intersect = 5823ms - Found 51
.Except = 6720ms - Found 51
Creating Events took 26ms
Number of Tags = 3000
Number of Products = 1003
Average Number of Tags per Products = 100
Number of Search Tags = 10
.All.Contains = 259ms - Found 51
.Intersect = 6417ms - Found 51
.Except = 7347ms - Found 51
使用HashSet
Creating Events took 6ms
Number of Tags = 3000
Number of Products = 1003
Average Number of Tags per Products = 100
Number of Search Tags = 10
.All.Contains = 5379ms - Found 51
.Intersect = 5823ms - Found 51
.Except = 6720ms - Found 51
Creating Events took 26ms
Number of Tags = 3000
Number of Products = 1003
Average Number of Tags per Products = 100
Number of Search Tags = 10
.All.Contains = 259ms - Found 51
.Intersect = 6417ms - Found 51
.Except = 7347ms - Found 51
如您所见,使用HashSet的速度要快得多,即使您将额外的20ms用于创建HashSet也是如此。尽管散列是ID字段的简单散列。如果使用更复杂的散列,结果会有所不同。您是有实际的性能问题还是试图提前优化?@Oren我正在尝试提前优化,因为项目正在开发中,db中只有10个测试产品/3个测试标记……优化的最佳方法是避免理论化和实际上,保留了大量的标签、产品及其关联——最好是比您预期的未来稍大一点。然后,您可以测试性能是否可以接受,而不是猜测不同的方法是否更好。