linq到实体的动态where子句作为字符串

本文关键字:子句 字符串 where 动态 实体 linq | 更新日期: 2023-09-27 17:57:36

我想通过为where子句提供字符串表达式,使用linq对实体动态筛选数据。

例如:

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

我怎么能做同样的事情,但这次是过滤某个字符串开头的数据?

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

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

linq到实体的动态where子句作为字符串

我认为您可能正在寻找的是动态LINQ。Scott Guthrie发布了这个:

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

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

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

这是我最近写的一个解决方案中startsWith使用的函数。这是一个巨大的痛苦,因为你不能在ctype或vb中的DirectCast中使用Type变量作为参数,也不能对同一类型的对象和可为null的对象进行linq比较。

请尝试以下操作:

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

HTH

忘记"魔术"字符串吧,C#是强类型的。无论如何,你最终会得到一个位置列表,所以最好的方法是让它们强类型化。

    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
    }