【问题标题】:Predicate Building with subquery using LinqKit使用 LinqKit 使用子查询构建谓词
【发布时间】:2017-09-26 11:54:29
【问题描述】:

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

例子:

我有 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; }
}

我有一个数据库上下文。

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;
}

但我收到错误消息:参数“f”未绑定在指定的 LINQ to Entities 查询表达式中。

如果我删除 A 行或 B 行,它执行时会出错。使用它们都会引发异常。

任何人都可以就我应该做些什么来实现这一点提供一些意见吗?

谢谢

【问题讨论】:

    标签: c# predicatebuilder linqkit


    【解决方案1】:

    看来我快到了。我只需要翻转 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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多