如何在 linq toEntity 和实体框架中过滤产品

问题描述 投票:0回答:1

我有一个表将

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

entity-framework filtering linq-to-entities
1个回答
0
投票

我终于明白了:

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);
© www.soinside.com 2019 - 2024. All rights reserved.