【问题标题】:linq to entities dynamic where clause as stringlinq 到实体动态 where 子句作为字符串
【发布时间】:2015-03-06 03:31:41
【问题描述】:

我想通过向 where 子句提供字符串表达式,使用 linq to 实体动态过滤数据。

例如:

string filterExpr = "it.City='London'"
var ret1 = Contex.Customers.Where(filterExpr);

我该如何做同样的事情,但这次要过滤某个字符串开头的数据?

如果使用字符串无法实现,如何构建合适的 Lambda 表达式?

(对我来说,能够通过许多参数(OR/AND)进行过滤也很重要)

【问题讨论】:

    标签: c# linq-to-entities


    【解决方案1】:

    我认为您可能正在寻找的是动态 LINQ。斯科特·格思里发布了这个:

    http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

    它没有使用 lambda 语法那么快,因为它们需要在运行时编译,但它可能是您的答案。

    【讨论】:

      【解决方案2】:
      Public Shared Function getFilterStartsWith(Of T)(ByVal param As ParameterExpression, ByVal prop As MemberExpression, ByVal arg As Object) As Expression
          Dim mi As MethodInfo = GetType(String).GetMethod("StartsWith", New Type() {GetType(String)}, Nothing)
          Return Expression.Lambda(Of Func(Of T, Boolean))(LambdaExpression.[Call](prop, mi, Expression.Constant(arg, GetType(String))), param)
      End Function
      

      在 C# 中:

      public static Expression getFilterStartsWith<T>(ParameterExpression param, MemberExpression prop, object arg) {
          MethodInfo mi = typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) }, null);
          return Expression.Lambda<Func<T, bool>>(LambdaExpression.Call(prop, mi, Expression.Constant(arg, typeof(string))), param);
      }
      

      这就是我在最近写的solution 中用于startsWith 的函数。事实证明这是一个巨大的痛苦,因为您不能将 Type 变量用作 ctype 中的参数或 vb 中的 DirectCast,并且您不能对同一类型的对象和可为空的对象进行 linq 比较。

      【讨论】:

      • 妈的,VB比我想象的还要冗长。
      • c# 语法不难的话请进
      【解决方案3】:

      请试试这个:

      var ret1 = contex.Customers.Where(x => x.it.City.StartsWith('l'));
      

      HTH

      【讨论】:

      • 制胜法宝!
      • 但我已经解释了我不能使用它!哪里不知道“x.it.City”,因为它在运行时获取属性来填充
      • 这并没有真正回答如何在字符串中动态指定过滤器的问题
      • 糟糕...我的错...你能试试这个吗:tring filterExpr = "it.City like 'L%'"。 HTH
      【解决方案4】:

      忘掉“魔法”字符串吧,C# 是强类型的。 一种或另一种方式 你最终会得到一个 where's 列表,所以最好的方法是让它们强类型化。

          public class Veg
          {
              public int Id { get; set; }
              public string Name { get; set; }
              public bool Fruit { get; set; }
          }
      
          enum Mode
          {
              One,
              Two,
              Three
          }
      
          static void Main()
          {
              Mode mode = Mode.One;
      
              var data = new List<Veg>
              {
                  new Veg{Id = 1, Name = "Apple", Fruit = true},
                  new Veg{Id = 2, Name = "Carrot", Fruit = false}
              };
      
              var dataSelect = data.Where(w => (mode == Mode.One && w.Fruit) || //only fruits
                                               (mode == Mode.Two && !w.Fruit) || //only not fruits
                                               (mode == Mode.Three)); //all of it
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-06-21
        • 2021-04-16
        • 1970-01-01
        • 1970-01-01
        • 2012-01-05
        • 2018-01-07
        • 2021-06-19
        • 1970-01-01
        相关资源
        最近更新 更多