【问题标题】:Dynamic Linq "Where statement" with Relation具有关系的动态 Linq“Where 语句”
【发布时间】:2016-12-04 00:52:51
【问题描述】:

我正在尝试使用 Dynamic Linq 和我自己计算的 where 字符串语句构建查询。例如:

List<Publication> results = new List<Publication>();

// Just an example, previously calculated dynamically
string filterQuery = "(Id = 1 and Number = 2)";

IQueryable<Publication> query = db.Publications.Include(i => i.Product);
query = query.Where(filterQuery);

results = query.OrderBy(orderQuery).ToList();

这很好用,我得到了包含产品的出版物列表。现在……问题是。如何使用 Dynamic Linq 和字符串语句创建字符串语句以根据与 Product 的关系获取结果?

类似:

string filterQuery = "(Id = 1 and Number = 2 and Products.Id = 1)"

【问题讨论】:

    标签: c# entity-framework visual-studio linq


    【解决方案1】:

    经过大量研究和尝试,这是使用相同 Dynamic Linq 库的一种简单友好的方式:

    List<Publication> results = new List<Publication>();
    
    // Just an example, previously calculated dynamically
    string filterQuery = "(Id = 1 and Number = 2)";
    string filterQueryChildren = "Products.Any(Id == 1)"
    
    IQueryable<Publication> query = db.Publications.Include(i => i.Product).Where(filterQueryChildren);
    
    query = query.Where(filterQuery);
    
    results = query.OrderBy(orderQuery).ToList();
    

    【讨论】:

      【解决方案2】:

      我不确定你为什么要这样做,但以下应该可以工作:

      List<Publication> results = new List<Publication>();
      
      // Just an example, previously calculated dynamically
      string filterQuery1 = "(Id = 1)"
      string filterQuery2 = "(Id = 1 and Number = 2)";
      
      IQueryable<Publication> query = db.Publications.
      Where(filterQuery1).     
      Include(i => i.Product);
      query = query.Where(filterQuery2);
      
      results = query.OrderBy(orderQuery).ToList();
      

      【讨论】:

      • 抱歉,这不起作用。我得到:“包含路径表达式必须引用在类型上定义的导航属性。对引用导航属性使用虚线路径,对集合导航属性使用 Select 运算符”。
      • 不!那是行不通的。假设 Id 和 Number 是 Publications 的属性,CategoryId 是 Products 的属性。我只想找到 Id = 1 和 Number = 2 的出版物,并包括 CategoryId(产品的)所在的产品,例如 3。您的示例给了我:“出版物”类型中不存在属性或字段“CategoryId”
      【解决方案3】:

      要进行动态 LINQ 查询,您需要一个支持它的库,或者使用 Expression Tree 自己进行操作

      见:Entity Framework Dynamic Query Library

      免责声明:我是项目的所有者Eval-Expression.NET

      此库允许您在运行时评估、编译和执行代码。

      该库还包含动态 LINQ 的扩展方法

      维基:Eval Dynamic LINQ

      例子

      // using Z.Expressions; // Don't forget to include this.
      
      // The filterQuery must use the C# syntax
      string filterQuery = "x.Id == 1 && x.Number = 2";
      
      IQueryable<Publication> query = db.Publications.Include(i => i.Product);
      query = query.Where(x => filterQuery);
      

      编辑:回答子问题

      很好,但是如何按产品过滤?

      Entity Framework 不支持 Include 方法中的过滤器。

      但是,EF+ 可以

      免责声明:我是Entity Framework Plus的所有者

      见:EF+ Query IncludeFilter

      通过结合这两个库,你可以达到你想要的结果:

      // Extension method must be registered, otherwise the library cannot be aware of which extension method exists!
      EvalManager.DefaultContext.RegisterExtensionMethod(typeof (QueryIncludeFilterExtensions));
      
      string where1 = "x.Id == 1 && x.Number == 2";
      string where2 = "y.Id == 3";
      
      var left2 = ctx.Publications
          .Where(x => where1)
          .Execute<IQueryable<Publication>>("IncludeFilter(x => x.Product.Where(y => " + where2 + "))")
          .ToList();
      

      如果您想尝试此解决方案,请确保下载最新版本的 Eval-Expression.NET。我们刚刚解决了几分钟前通过尝试您的方案发现的问题。

      EDIT2:回答子问题

      这是我向您推荐的。

      在没有我们的库的情况下尝试查询,然后动态尝试。

      这样更容易找到编译错误或者你真正想做的事情。

      例如,我们可能没有正确理解最初的问题并建议了您不想要的 IncludeFilter。我假设您想过滤多个产品。但是,看起来每个出版物只有一个产品,因此 Where 子句方法显然不存在。

      也许这就是你要找的东西:

      string where1 = "x.Id == 1 && x.Number == 2 && x.Product.Id == 3";
      
      var left2 = ctx.Publications
          .Include(x => x.Product)
          .Where(where1)
          .ToList();
      

      所以简而言之,通过硬编码(不使用动态)来尝试查询,然后你就会知道如何动态使用它。

      【讨论】:

      • 很好,但我如何按产品过滤?例如:x.Id == 1 && x.Number ==2 用于出版物。我可以制作类似 x.Id == 1 && x.Number ==2 && i.Id = 1 的东西吗???? (x 代表出版物,i 代表产品)
      • 感谢您的回答乔纳森。所以...我得到了用于 Eval-Expression.NET 和 Entity Framework Plus 的 NuGet 包,我在 Controller 的方法中注册了库,我准备好了吗?
      • 是的,完全正确。请注意,EF+ 始终是免费的,但 Eval-Expression.NET 在达到 50 个字符之前都是免费的(应该没问题)。让我知道你是否成功使它工作。
      • 抱歉,这不起作用。我明白了:哎呀!未找到表达式的适用成员。然后我将产品更改为产品,现在错误是:哎呀! EF+ Query IncludeFilter 不支持选择投影。欲了解更多信息,请联系我们:info@zzzprojects.com。
      • 能秀一下表情吗?我们显然用上面的代码测试它没有问题。如果需要,您可以直接与我们联系。它可能会更容易。我们的电子邮件在错误消息中;)
      猜你喜欢
      • 1970-01-01
      • 2013-01-15
      • 2010-10-16
      • 2021-04-16
      • 2019-02-02
      • 1970-01-01
      • 2023-03-29
      • 2010-10-25
      • 1970-01-01
      相关资源
      最近更新 更多