`
wyf
  • 浏览: 436498 次
  • 性别: Icon_minigender_1
  • 来自: 唐山
社区版块
存档分类
最新评论

动态构建Expression表达式树

    博客分类:
  • C#
阅读更多

动态构建Expression表达式树

话说.Net已经发展到4.5了,大家对Lambda和Linq应该比较熟悉了。比如我们要取出产品集合里面SKU以"123"开头的产品集,就可以这么写:
Products=Products.Where(p=>p.SKUCode.StartWith("123"));

 

现下有这么个需求,用户输入以逗号分隔的字符串,求取SKU以分隔的字符串开头的产品集,如用户输入"123,234,456",那么就取出SKU以"123"开头或以"234"开头或以"456"开头的产品集合。于是我计上心头,欲以循环解之,无解。为什么呢?因为这里有个关键字“或”。假如是“并”需求,我们大可信手拈来,如下:

 string[] starts = input.Split(',');
 foreach (string start in starts)
 {
     Products = Products.Where(p => p.SKUCode.StartWith(start));
 }

 对于“或”来说,Linq似乎并没有提供一个明确的方法(比如这里的Where)供我们使用,我想是因为“或”的作用域比较难用程序语言界定,因此一旦使用“或”去联接,那最终的结果可能并不是预期的。若“或”对应的方法是Or,那么循环体内的语句变为Products = Products.Or(p => p.SKUCode.StartWith(start));不知所云。我们想要的其实应该是条件的拼接:

p => p.SKUCode.StartWith(start1) || p.SKUCode.StartWith(start2) || p.SKUCode.StartWith(start3) || ……

可惜Linq同样没有给我们提供动态拼接条件的方便的语法(何为方便,我的想法是同字符串拼接,拼接完毕后可简单快捷地转成可执行的语句。啥,你说Javascript?心里想想就是了,说出来干嘛),不过给了稍稍复杂点的方式。下面是代码: 

/// <summary>
/// 根据条件数据动态生成或连接条件
/// </summary>
/// <typeparam name="TSource">集合项类型</typeparam>
/// <param name="sourcePropertyName">待比较的集合项属性</param>
/// <param name="methodName">方法名称</param>
/// <param name="objs">条件数据</param>
/// <returns></returns>
public static Expression<Func<TSource, bool>> GenerateOrElseConditionWithArray<TSource>(string sourcePropertyName, string methodName, IEnumerable<object> objs)
{
    if (objs != null && objs.Count() > 0)
    {
        var len = objs.Count();
        var p = Expression.Parameter(typeof(TSource), "p");
        var propertyName = Expression.Property(p, sourcePropertyName);
        var body = Expression.Equal(Expression.Call(propertyName, methodName, null, Expression.Constant(objs.First())), Expression.Constant(true));
        for (int i = 1; i < len; i++)
        {
            var pcode = objs.ElementAt(i);
            body = Expression.OrElse(body, Expression.Call(propertyName, methodName, null, Expression.Constant(pcode)));
        }
        Expression<Func<TSource, bool>> orExp = Expression.Lambda<Func<TSource, bool>>(body, p);
        return orExp;
    }
    return null;
}

 现在我们就可以这么实现上述需求:

 
 string[] starts = input.Split(',');
 var codeExp = GenerateOrElseConditionWithArray<Product>("SKUCode", "StartsWith", starts);
 if (codeExp != null)
     Products = Products.Where(codeExp);
 
后记:老外写了一个类,貌似比我的专业多了,Dynamically Composing Expression Predicates.

 

 转载请注明本文出处:http://www.cnblogs.com/newton/archive/2012/12/17/2821159.html

分享到:
评论

相关推荐

    Expression表达式树动态查询.zip

    "Expression表达式树动态查询.zip"中的内容显然是关于如何使用C#表达式树来构建动态查询的示例或教程。 表达式树(Expression Tree)是将代码表示为树形结构,其中每个节点都是代码的一部分,如变量、操作符、方法...

    二叉树(C语言)以及构建表达式树

    在提供的压缩包`expressiontree`中,应包含实现上述功能的源代码,如`createTree.c`用于构建表达式树,`traversal.c`包含遍历函数,`main.c`则包含测试代码。通过运行`main.c`,你可以观察到二叉树操作的实际效果,...

    表达式解析之表达式树的建立

    表达式树(Expression Tree)是一种树形结构,其中每个内部节点代表一个运算符,而每个叶节点则代表操作数。这种结构直观地反映了表达式的运算顺序和优先级,对于理解和处理复杂表达式非常有用。例如,表达式 "2 + 3...

    C#表达式树教程

    在C#编程中,表达式树(Expression Tree)是一种数据结构,它以树的形式表示了程序中的表达式。表达式树对于理解代码逻辑、编译器优化、动态代码执行以及 LINQ 查询等场景有着重要的作用。本教程将深入探讨表达式树...

    表达式树的应用

    #### 一、动态创建表达式树 表达式树是一种用于表示编程语言中的表达式的数据结构。它将表达式转换成一个可以被编译器理解和执行的对象模型。这对于动态地创建和操作代码尤其有用。本节主要介绍如何动态创建表达式...

    C#基于表达式(Expression)实现对象深拷贝

    而使用表达式树可以更高效地创建深拷贝,因为它允许我们在运行时动态生成代码,避免了序列化的开销。 以下是一个基于表达式实现深拷贝的基本步骤: 1. **创建深拷贝辅助类**:定义一个静态类,如`DeepCopyHelper`...

    06.C# 知识回顾 - 表达式树 Expression Trees.pdf

    在LINQ中,开发者可以编写表达式树来构建查询,并且这些查询可以被转换为SQL语句来执行,特别是在数据库操作中。 表达式树提供了一种在运行时动态操作代码的机制,允许程序在不需要事先编译的情况下,根据表达式树...

    LINQ与DLR的Expression tree(4):创建静态类型的LINQ表达式树节点

    2. **创建表达式树**:演示了如何使用C#代码动态构建表达式树,例如创建一个表示数学运算(如加法、乘法)的表达式树,或者构建包含方法调用的表达式树。 3. **静态类型与动态类型**:讨论了在创建表达式树时如何...

    C#之Expression表达式树实例

    C#的Expression表达式树提供了一种灵活的方式来处理代码,不仅适用于LINQ查询,还适用于动态编译和运行代码、生成元编程解决方案等场景。通过理解表达式树的工作原理和构建方式,开发者可以更高效地编写出强大且灵活...

    面向对象的方式表达式树实现

    此外,为了构建表达式树,可能还需要一个辅助函数,如`parseExpression`,它接收一个字符串形式的表达式,然后返回一个根节点。这个函数会使用栈来处理括号,解析运算符和操作数,并创建相应的`ExprNode`实例。 ...

    回答问答和论坛的几个小程序,包括了表达式树代替反射的例子等

    在C#编程中,表达式树(Expression Trees)和反射是两种重要的技术,它们在处理动态行为和元数据方面有着广泛的应用。本压缩包文件包含了多个小程序,这些程序旨在帮助开发者理解和运用这两种技术,特别是在回答问答...

    动态构建Linq表达式

    而动态构建Linq表达式则是Linq的一个高级用法,允许我们在运行时根据需求构建查询表达式树。这在处理动态查询、元编程和自定义查询提供程序时非常有用。 标题"动态构建Linq表达式"指的是通过编程方式生成Linq查询...

    二叉表达式树

    二叉表达式树,也称为运算符树或语法树,是一种数据结构,它在计算机科学中用于表示数学或逻辑表达式。这种树形结构能够直观地展现表达式的运算顺序和结构,使得计算变得简单,同时也方便了编译器进行解析和优化。在...

    表达式树和泛型缓存完成Mapper效果

    利用表达式树,我们可以动态地构建和编译映射规则。例如,我们可以创建一个方法,接受两个类型参数(源类型和目标类型),然后构建一个表达式,该表达式遍历源对象的所有公开属性,并将它们设置到目标对象的相应属性...

    将给定的表达式树(二叉树)转换为等价的中缀表达式(通过括号反映操作符的计算次序)并输出

    在实际实现时,我们需要注意表达式树的构建步骤,这可能因输入方式而异。例如,我们可以使用一个列表来存储操作符和操作数,然后将其转换为表达式树。下面是一个简单的示例代码: ``` # 创建表达式树 root = Node('...

    IK Expression开源表达式解析器 V2.1.2.rar

    语法分析则根据一定的语法规则,将这些标记组合成抽象语法树(AST),这棵树代表了表达式的结构。在IK Expression V2.1.2中,优化的算法确保了这两个过程的高效执行。 此版本的IK Expression解析器V2.1.2可能包含...

    rpn.zip_rpn_表达式树c++

    在IT领域,表达式树(Expression Tree)是一种用于表示数学或逻辑表达式的数据结构,它以树状形式展示了表达式的结构。在这个特定的项目“rpn.zip_rpn_表达式树c++”中,我们主要关注如何将中缀表达式(Infix ...

    浅谈c#表达式树Expression简单类型比较demo

    这个示例展示了如何利用C#表达式树动态地构建比较逻辑,使得我们可以在运行时根据需要生成不同的比较操作。这在某些情况下非常有用,比如在构建动态查询或自定义逻辑时,可以避免硬编码特定的比较操作,从而提高代码...

    05 Expression.zip

    《严蔚敏数据结构与算法实现》是一本深入讲解数据结构和算法的教材,其中"05 Expression"部分主要涉及表达式树这一重要的数据结构及其相关的算法。在计算机科学中,数据结构是组织和存储数据的方式,而算法则是解决...

Global site tag (gtag.js) - Google Analytics