我有一个表将
Products
映射到 Specs
和 SpecOptions
和 SpecUnits
:
MapProductSpecOptionSpecUnitSpec
表:
public class MapProductSpecOptionSpecUnitSpec
{
[Key, Column(Order = 0)]
public int ProductId {get; set;}
[Key, Column(Order = 1)]
public int SpecId {get; set;}
[Key, Column(Order = 2)]
public int SpecOptionId {get; set;}
public int? SpecUniId {get; set;}
}
Spec
:
public class Spec
{
[Key, Column(Order = 0)]
public int Id {get; set;}
public virtual ICollection<SpecOption> Options {get; set;}
public virtual ICollection<MapProductSpecOptionSpecUnitSpec> Maps {get; set;}
}
规格选项:
public class SpecOption
{
[Key, Column(Order = 0)]
public int Id {get; set;}
public virtual Spec Spec {get; set;}
public int SpecId {get; set;}
public virtual ICollection<MapProductSpecOptionSpecUnitSpec> Maps {get; set;}
}
我从用户那里得到了
SpecId
、SpecOptionId
和 SpecUnitId
,需要注意的是,SpecUnitId
可能为 NULL。
我需要同时满足我所有标准的
Products
,而不仅仅是其中之一。
换句话说,它必须是 Spec 之间的
AND
和 Spec 的 SpecOptions 之间的 OR
。
示例:
SpecId SpecOptionId SpecUnit
----------------------------------
15 24 NULL
6 71 6
7 72 2
我现在是怎么做的:
var maps = _db.MapProductSpecOptionSpecUnitSpec.AsQueryable();
var specPredicate = PredicateBuilder.New<MapProductSpecOptionSpecUnitSpec>();
foreach (var gp in model.GroupBy(x => x.SpecId))
{
var optionPredicate = PredicateBuilder.New<MapProductSpecOptionSpecUnitSpec>();
foreach (var map in gp)
{
optionPredicate = optionPredicate.Or(y => y.SpecOptionId == y.OptionId && map.UnitId == map.UnitId);
}
specPredicate = specPredicate.And(optionPredicate);
}
var query = maps.AsExpandable().Where(specPredicate).Select(x => x.Product);
虽然我有符合这些条件的产品,但执行查询时我什么也没得到。
我怎样才能实现这个目标?
注意:我正在使用Albahari的PredicateBuilder
我终于明白了:
var predicate = PredicateBuilder.New<Product>();
foreach (var filterGp in filters.GroupBy(x => x.SpecId)) {
var innerPredicate = PredicateBuilder.New<Product>();
foreach (var filter in filterGp) {
innerPredicate = innerPredicate.Or(x => x.MapProductSpecOptionSpecUnitSpec.Any(y => y.SpecOptionId == filter.OptionId && y.SpecUnitId == filter.UnitId));
}
predicate = predicate.And(innerPredicate);
}
query = query.AsExpandable().Where(predicate);