使用LinqKit使用子查询进行谓词构建

时间:2017-04-28 11:15:59

标签: c# predicatebuilder linqkit

我正在尝试研究如何使用引用父查询的子查询来构建谓词。

示例:

我有2个班级(当然是Foo和Bar)。

Bar的ReferenceId指(在此特定情况下)Foo的Id。

public class Foo
{
    public int Id { get; set; }

    public bool IsGood { get; set; }
}

public class Bar
{
    public int Id { get; set; }

    public int ReferenceId { get; set; }

    public bool IsSomething { get; set; }
}

我有一个DB上下文。

public class MyContext : DbContext
{
    public DbSet<Foo> Foos { get; set; }
    public DbSet<Bars> Bars { get; set; }
}

我想使用一个谓词构建器(如果可能的话)来创建一个这样的函数...它会检查一个带有Foo的Id的Bar的存在。

我没有Bar作为导航属性,所以我需要直接访问上下文。

public static IQueryable<Foo> GetFooQuery(IQueryable<Foo> query, MyContext context)
{
    query = query.Where(f => f.IsGood)
                 .Where(f => context.Bars.Where(b => b.ReferenceId == f.Id)
                                         .Where(b => b.IsSomething)
                                         .Any());

    return query;
}

我发现了这个(我认为)与我想要的相似,但不一样。

Entity Framework Code First 4.3 / LINQKit predicate for related table

我写了这个

public static IQueryable<Foo> GetFooQuery(IQueryable<Foo> query, MyContext context)
{
    var barPredicateBuilder = PredicateBuilder.True<Bar>();
    barPredicateBuilder = barPredicateBuilder.And(b => b.IsSomething);

    var fooPredicateBuilder = PredicateBuilder.True<Foo>();
    fooPredicateBuilder = fooPredicateBuilder.And(f => f.IsGood);
    fooPredicateBuilder = fooPredicateBuilder.And(f => context.Bars
                                                              .Where(b => b.ReferenceId == f.Id) // A
                                                              .Where(barPredicateBuilder).AsExpandable() // B
                                                              .Any());

    query = query.Where(fooPredicateBuilder).AsExpandable();

    return query;
}

但我收到了错误:参数&#39; f&#39;未绑定在指定的LINQ to Entities查询表达式中。

如果我删除A行或B行,则会执行错误。与他们俩一起,它抛出异常。

有人可以就我应该做些什么来提供一些意见吗?

由于

1 个答案:

答案 0 :(得分:0)

好像我差不多了。我只需要翻转A和B行。

public static IQueryable<Foo> GetFooQuery(IQueryable<Foo> query, MyContext context)
{
    var barPredicateBuilder = PredicateBuilder.True<Bar>();
    barPredicateBuilder = barPredicateBuilder.And(b => b.IsSomething);

    var fooPredicateBuilder = PredicateBuilder.True<Foo>();
    fooPredicateBuilder = fooPredicateBuilder.And(f => f.IsGood);
    fooPredicateBuilder = fooPredicateBuilder.And(f => context.Bars
                                                              .Where(barPredicateBuilder).AsExpandable() // B
                                                              .Where(b => b.ReferenceId == f.Id) // A
                                                              .Any());

    query = query.Where(fooPredicateBuilder).AsExpandable();

    return query;
}