在Linq To EF中,如何用委托动态生成查询条件?

时间:2022-04-22 12:01:19
代码如下,问题是如何动态返回:Expression<Func<Web_Base_News_Info, bool>> expression?
有其它更好的办法也可以,谢谢。

public void Test(ContextExt ctx, Params.FieldExtRepeater fieldExt)
{
    // 1.封装容器
    var ft = new FieldTest<Web_Base_News_Info>();
    // 封装key对应的变量
    ft._dictKey.Add(EnumsKV.FieldKeyValues.PkId, p => p.PkId);
    ft._dictKey.Add(EnumsKV.FieldKeyValues.FlagStatus, p => p.flagStatus ?? 0);
    ft._dictKey.Add(EnumsKV.FieldKeyValues.FlagView, p => p.flagView ?? 0);
    ft._dictKey.Add(EnumsKV.FieldKeyValues.FlagPass, p => p.flagPass ?? 0);
    // 2.封装method对应的变量
    ft._dictMethod.Add(EnumsKV.FieldMethodValues.Equal, (p, q) => p == q);
    ft._dictMethod.Add(EnumsKV.FieldMethodValues.Great, (p, q) => p > q);
    ft._dictMethod.Add(EnumsKV.FieldMethodValues.Less, (p, q) => p < q);
    ft._dictMethod.Add(EnumsKV.FieldMethodValues.NotEqual, (p, q) => p != q);
    ft._dictMethod.Add(EnumsKV.FieldMethodValues.NotGreat, (p, q) => p <= q);
    ft._dictMethod.Add(EnumsKV.FieldMethodValues.NotLess, (p, q) => p >= q);
    // 3.动态生成查询条件
    Expression<Func<Web_Base_News_Info, bool>> whereOr = PredicateBuilder.False<Web_Base_News_Info>();
    var 查询条件 = whereOr;
    查询条件 = 查询条件.Or(w => w.flagStatus == 3);     // 示例:固定查询条件,下面的动态生成条件类似于这个
    foreach (var ifvs in fieldExt.FieldWhereOr)         // 要求:动态查询条件
    {
        var ifv = ifvs as IntItem;
        Expression<Func<Web_Base_News_Info, bool>> expression = ft.这里如何返回正确的Expression呢(ifv.Key, ifv.Method, ifv.Value);
        查询条件 = 查询条件.Or(expression);
    }
    var 结果二 = ctx.Web_Base_News_Info.AsQueryable().Where(查询条件);
    Response.Write("::B.有" + 结果二.Count() + "个【得0个,实际是5个】::<br />\r\n");
}
public class FieldTest<T>
{
    public Dictionary<EnumsKV.FieldKeyValues, Func<T, int>> _dictKey = new Dictionary<EnumsKV.FieldKeyValues, Func<T, int>>();
    public Dictionary<EnumsKV.FieldMethodValues, Func<int, int, bool>> _dictMethod = new Dictionary<EnumsKV.FieldMethodValues, Func<int, int, bool>>();
    public Expression<Func<T, bool>> 这里如何返回正确的Expression呢(EnumsKV.FieldKeyValues key, EnumsKV.FieldMethodValues method, int value)
    {
        Func<T, int> func1 = _dictKey[key];
        Func<int, int, bool> func2 = _dictMethod[method];
        Expression<Func<T, bool>> exp = p => func2(func1(p), value);
        return exp;
    }
}
public enum FieldKeyValues // 枚举字段名称
{
    PkId = 1,
    flagStatus = 2,
    flagView = 4,
    flagPass = 8,
}
public enum FieldMethodValues
{
    /// <summary>
    /// Int32、Float、DataTime
    /// </summary>
    [Description("大于")]
    Great,
    [Description("不大于")]
    NotGreat,
    [Description("小于")]
    Less,
    [Description("不小于")]
    NotLess,
    [Description("等于")]
    Equal,
    [Description("不等于")]
    NotEqual,
}

7 个解决方案

#1


EF有个库叫Dynamic LINQ

你看看如果它能够满足你的条件,你就不用自己开发了。
http://weblogs.asp.net/scottgu/dynamic-linq-part-1-using-the-linq-dynamic-query-library

#3


不行啊,我要的是,通过委托,动态的生成,而且是在未知条件的情况下,楼上两位朋友列的都是已知条件的例子。

#4





  public class TT
        {
            public int id { get; set; }
        }
        public static void Main()
        {
            //动态构建下面这个表达式树
            Expression<Func<TT, bool>> ddd = x => x.id == 0;

            var entitytype = Expression.Parameter(typeof(TT), "x");
            var property = typeof(TT).GetProperty("id");
            var key = Expression.MakeMemberAccess(entitytype, property);

            var value = Expression.Constant(0);
            var term = BinaryExpression.Equal(key, value);
            var lambda = Expression.Lambda(term, entitytype);
            var func = lambda.Compile();

            TT testobject = new TT() { id = 0 };
            object result1 = func.DynamicInvoke(testobject);
            object result2 = ddd.Compile().DynamicInvoke(testobject);
            Console.WriteLine(result1);
            Console.WriteLine(result2);
        }



这样就可以动态构建Expression<Func<T,bool>>了。。

我看了下1楼发的Dynamic LINQ。我也是看了才知道有这东西。我觉得这东西挺好,可以满足你

#5


什么未知情况,写个泛型方法应该可以解决

#6


dlinq允许你拼接字符串得到linq查询
或者你可以自己解析,然后构造表达式树来做。

#7


你要返回Expression<Func<T,bool>>,那么前提,你的未知条件也必然要有一种表达方式。
由于你要返回的就是lambda表达式,所以你传入的东西,要么是类似于拼接的string,要么就是一种自己定义的条件表达式类型。
不论是哪种,都建议你直接拼接成ESQL直接给Linq2EF执行更为方便。
如果执意要Expression<Func<T,bool>>的话,找微软直接提供代码的动态构建lambda表达式的类库 System.Linq.Dynamic.DynamicQueryable 可以基本满足你的要求,只需要些许处理。它返回的是LambdaExpression,是Expression<>的基类,你可以构建一个永真Expression<>再调用Update方法将动态构建的lambda表达式的逻辑加入,最后就可以得到你要的Expression<Func<T,bool>>了

#1


EF有个库叫Dynamic LINQ

你看看如果它能够满足你的条件,你就不用自己开发了。
http://weblogs.asp.net/scottgu/dynamic-linq-part-1-using-the-linq-dynamic-query-library

#2


#3


不行啊,我要的是,通过委托,动态的生成,而且是在未知条件的情况下,楼上两位朋友列的都是已知条件的例子。

#4





  public class TT
        {
            public int id { get; set; }
        }
        public static void Main()
        {
            //动态构建下面这个表达式树
            Expression<Func<TT, bool>> ddd = x => x.id == 0;

            var entitytype = Expression.Parameter(typeof(TT), "x");
            var property = typeof(TT).GetProperty("id");
            var key = Expression.MakeMemberAccess(entitytype, property);

            var value = Expression.Constant(0);
            var term = BinaryExpression.Equal(key, value);
            var lambda = Expression.Lambda(term, entitytype);
            var func = lambda.Compile();

            TT testobject = new TT() { id = 0 };
            object result1 = func.DynamicInvoke(testobject);
            object result2 = ddd.Compile().DynamicInvoke(testobject);
            Console.WriteLine(result1);
            Console.WriteLine(result2);
        }



这样就可以动态构建Expression<Func<T,bool>>了。。

我看了下1楼发的Dynamic LINQ。我也是看了才知道有这东西。我觉得这东西挺好,可以满足你

#5


什么未知情况,写个泛型方法应该可以解决

#6


dlinq允许你拼接字符串得到linq查询
或者你可以自己解析,然后构造表达式树来做。

#7


你要返回Expression<Func<T,bool>>,那么前提,你的未知条件也必然要有一种表达方式。
由于你要返回的就是lambda表达式,所以你传入的东西,要么是类似于拼接的string,要么就是一种自己定义的条件表达式类型。
不论是哪种,都建议你直接拼接成ESQL直接给Linq2EF执行更为方便。
如果执意要Expression<Func<T,bool>>的话,找微软直接提供代码的动态构建lambda表达式的类库 System.Linq.Dynamic.DynamicQueryable 可以基本满足你的要求,只需要些许处理。它返回的是LambdaExpression,是Expression<>的基类,你可以构建一个永真Expression<>再调用Update方法将动态构建的lambda表达式的逻辑加入,最后就可以得到你要的Expression<Func<T,bool>>了