我有一个sql查询,它执行我之后选择的类型:
select * from Products p where p.ProductId in (
select distinct ProductId from ProductFacets
where ProductId in (select ProductId from ProductFacets where FacetTypeId = 1)
and ProductId in (select ProductId from ProductFacets where FacetTypeId = 4)
)
可以将多个FacetTypeIds传递到此查询中。
此查询是在基于int []类型的参数参数的方法中构造的。
public IEnumerable<Product> GetProductsByFacetTypes(string productTypeSysName, int[] facetTypeIds)
我正在尝试研究如何在LINQ中实现这一目标。到目前为止,我想出了类似的东西:
var products = from p in sc.Products
where p.ProductType.SysName == productTypeSysName
where p.FacetTypes.Any(x => x.FacetTypeId == 1)
where p.FacetTypes.Any(x => x.FacetTypeId == 4)
select p;
返回正确的结果集。
但是我不确定如何使用int [] facetTypeIds参数构建此查询。
编辑:
ProductFacets包含以下数据:
ProductId, FacetTypeId
1, 1
1, 2
2, 1
2, 3
3, 4
3, 5
4, 1
4, 2
例如,我希望能够只选择FacetTypeId为1和2的产品。 结果集应包含ProductIds 1和4
答案 0 :(得分:3)
可以通过调用Contains:
将本地集合传输到数据库from ft in facetTypes
where facetTypeIds.Contains(ft.FacetTypeId)
select ft;
本地集合被转换为sql参数。 Sql Server的参数限制为~2100,所以要小心。
具有任何方面的产品
from p in sc.Products
where p.ProductType.SysName == productTypeSysName
where
(
from ft in p.FacetTypes
where facetTypeIds.Contains(ft.FacetTypeId)
select ft
).Any()
select p;
具有各方面的产品。
int facetCount = facetTypeIds.Count();
from p in sc.Products
where p.ProductType.SysName == productTypeSysName
where
(
from ft in p.FacetTypes
where facetTypeIds.Contains(ft.FacetTypeId)
select ft.FacetTypeId
).Distinct().Count() == facetCount
select p;
答案 1 :(得分:1)
var facetTypeIds = new [] { 1, 4, ... };
var predicate = PredicateBuilder.True<Product>();
foreach (int id in facetTypeIds)
{
int facetId = id; // avoid capturing loop variable
predicate = predicate.And( p => p.FacetTypes.Any( x => x.FacetTypeId == facetId );
}
var products = sc.Products
.Where( p => p.ProductType.SysName == productTypeSysName )
.Where( predicate );
原文(错误,但留给上下文):
您想使用Contains
。另请注意,您可以使用逻辑并将多个Where子句替换为单个Where子句。
var facetTypeIds = new [] { 1, 4, ... };
var products = from p in sc.Products
where p.ProductType.SysName == productTypeSysName
&& p.FacetTypes.Any( x => facetTypeIds.Contains( x.FacetTypeId ) )
select p;
答案 2 :(得分:0)
这是基于tvanfosson的代码。我对这种方法的表现有疑问。
var facetTypeIds = new [] { 1, 4, ... };
var products = from p in sc.Products
where p.ProductType.SysName == productTypeSysName
&& facetTypeIds.All(ft => p.FacetTypes.Any(x => x.FacetTypeId == ft))
select p;