Util应用程序框架公共操作类(十一):表达式生成器

  本篇介绍的表达式生成器,用于动态创建表达式。

  在Util项目Lambdas目录中,添加ExpressionBuilder,代码如下。

using System;
using System.Linq.Expressions;

namespace Util.Lambdas {
    /// <summary>
    /// 表达式生成器
    /// </summary>
    public class ExpressionBuilder<TEntity> {
        /// <summary>
        /// 初始化表达式生成器
        /// </summary>
        public ExpressionBuilder() {
            Parameter = Expression.Parameter( typeof( TEntity ), "t" );
        }

        /// <summary>
        /// 参数
        /// </summary>
        private ParameterExpression Parameter { get; set; }

        /// <summary>
        /// 获取参数
        /// </summary>
        public ParameterExpression GetParameter() {
            return Parameter;
        }

        /// <summary>
        /// 创建表达式
        /// </summary>
        /// <param name="property">属性表达式</param>
        /// <param name="operator">运算符</param>
        /// <param name="value">值</param>
        public Expression Create<T>( Expression<Func<TEntity, T>> property, Operator @operator, object value ) {
            return Parameter.Property( Lambda.GetMember( property ) ).Operation( @operator, value );
        }

        /// <summary>
        /// 转换为Lambda表达式
        /// </summary>
        /// <param name="expression">表达式</param>
        public Expression<Func<TEntity, bool>> ToLambda( Expression expression ) {
            if ( expression == null )
                return null;
            return expression.ToLambda<Func<TEntity, bool>>( Parameter );
        }
    }
}

  在Util.Tests测试项目中,添加ExpressionBuilderTest单元测试,代码如下。

using System;
using System.Linq.Expressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Util.Lambdas;
using Util.Tests.Samples;

namespace Util.Tests {
    /// <summary>
    /// 测试表达式生成器
    /// </summary>
    [TestClass]
    public class ExpressionBuilderTest {
        /// <summary>
        /// 表达式生成器
        /// </summary>
        ExpressionBuilder<Test2> _builder;

        /// <summary>
        /// 测试初始化
        /// </summary>
        [TestInitialize]
        public void TestInit() {
            _builder = new ExpressionBuilder<Test2>();
        }

        /// <summary>
        /// 创建表达式
        /// </summary>
        [TestMethod]
        public void TestCreate_Int() {
            Expression<Func<Test2, int>> property = t => t.Int;
            var expression = _builder.Create( property, Operator.Equal, 1 );
            Expression<Func<Test2, bool>> expected = t => t.Int == 1;
            Assert.AreEqual( expected.ToString(), _builder.ToLambda( expression ).ToString() );
        }

        /// <summary>
        /// 创建表达式
        /// </summary>
        [TestMethod]
        public void TestCreate_Int_Nullable() {
            Expression<Func<Test2, int?>> property = t => t.NullableInt;
            var expression = _builder.Create( property, Operator.Equal, 1 );
            Assert.AreEqual( "t => (t.NullableInt == 1)", _builder.ToLambda( expression ).ToString() );
        }
    }
}

  由于目前的功能比较简单,所以只添加了两个方法,后面需要的时候再扩展。

  准备工作已经就绪,下一篇可以介绍查询条件及日期范围、数值范围条件封装。

  .Net应用程序框架交流QQ群: 386092459,欢迎有兴趣的朋友加入讨论。

  谢谢大家的持续关注,我的博客地址:http://www.cnblogs.com/xiadao521/

  下载地址:http://files.cnblogs.com/xiadao521/Util.2015.1.6.1.rar

时间: 2024-10-18 16:25:09

Util应用程序框架公共操作类(十一):表达式生成器的相关文章

Util应用程序框架公共操作类(十二):Lambda表达式公共操作类(三)

今天在开发一个简单查询时,发现我的Lambda操作类的GetValue方法无法正确获取枚举类型值,以至查询结果错误. 我增加了几个单元测试来捕获错误,代码如下. /// <summary> /// 测试值为枚举 /// </summary> [TestMethod] public void TestGetValue_Enum() { var test1 = new Test1(); test1.NullableEnumValue = LogType.Error; //属性为枚举,值

Util应用程序框架公共操作类(六):验证扩展

前面介绍了仓储的基本操作,下面准备开始扩展查询,在扩展查询之前,首先要增加两个公共操作类,一个是经常要用到的验证方法,另一个是Lambda表达式的操作类. 很多时候,我们会判断一个对象是否为null,由于null是一个不能接受的值,它会导致“未将对象引用设置到对象的实例”的严重错误,所以当检测到null值时一般直接抛出ArgumentNullException异常. public void Test( string name ) { if( name == null ) throw new Ar

Util应用程序框架公共操作类(四):验证公共操作类

为了能够验证领域实体,需要一个验证公共操作类来提供支持.由于我将使用企业库(Enterprise Library)的验证组件来完成这项任务,所以本文也将演示对第三方框架的封装要点. .Net提供了一个称为DataAnnotations的验证技术,即在对象的属性上添加一些Attribute,比如[Required]用来验证必填项.这是非常强大的特性,通过附加元数据的方式来提供验证,甚至在Mvc框架中还能自动生成Js客户端验证,从而可以非常方便的实现客户端和服务端的双重验证. 但是遗憾的是,.Net

Util应用程序框架公共操作类(三):数据类型转换公共操作类(扩展篇)

上一篇以TDD方式介绍了数据类型转换公共操作类的开发,并提供了单元测试和实现代码,本文将演示通过扩展方法来增强公共操作类,以便调用时更加简化. 下面以字符串转换为List<Guid>为例进行讨论. string input = "83B0233C-A24F-49FD-8083-1337209EBC9A,EAB523C6-2FE7-47BE-89D5-C6D440C3033A"; var result = Util.Conv.ToGuidList( input ); 观察上面

Util应用程序框架公共操作类(五):异常公共操作类

任何系统都需要处理错误,本文介绍的异常公共操作类,用于对业务上的错误进行简单支持. 对于刚刚接触.Net的新手,碰到错误的时候,一般喜欢通过返回bool值的方式指示是否执行成功. public bool 方法名() { //执行代码,成功返回true,否则返回false } 不过上面的方法有一个问题是,无法知道确切的错误原因,所以需要添加一个out参数来返回错误消息. public bool 方法名( out string errorMessage ) { //执行代码,成功返回true,否则返

Util应用程序框架公共操作类(一):数据类型转换公共操作类(介绍篇)

本系列文章将介绍一些对初学者有帮助的辅助类,这些辅助类本身并没有什么稀奇之处,如何能发现需要封装它们可能更加重要,所谓授之以鱼不如授之以渔,掌握封装公共操作类的技巧才是关键,我会详细说明创建这些类的动机和思考过程,以帮助初学者发现和封装自己需要的东西.创建公共操作类的技巧,大家可以参考我的这篇文章——应用程序框架实战十二:公共操作类开发技巧(初学者必读). 封装公共操作类,不仅要把技术上困难的封装进来,还需要不断观察自己的代码,以找出哪些部分可以更加简化.本文将介绍一个容易被大家所忽视的东西——

Util应用程序框架公共操作类(十):可空值类型扩展

当你使用可空的值类型时,你会发现取值很不方便,比如Guid? obj,你要从obj中获取值,可以使用Value属性obj. Value,但obj可能为null,这时候就会抛出一个异常. 可空值类型提供了一个HasValue属性,它可以识别出obj是不是一个null值,每当你获取可空值都需要加上这个判断if(value.HasValue){ var value = obj.Value;}. 下面我们通过几个扩展方法,把判断封装起来. 在Util项目中添加Extensions.Nullable.cs

应用程序框架实战十二:公共操作类开发技巧(初学者必读)

本文专门为初学者而写,因为很多初学者可能还不了解公共操作类的作用和封装技巧,大部分有经验的程序员都会把自己所碰到的技术问题整理封装成类,这就是公共操作类.公共操作类往往具有一些通用性,也可能专门解决某些棘手问题.公共操作类是应用程序框架的核心,主要目标是解决大部分技术问题.我将在本文介绍封装公共操作类的要点,供初学者参考. 开发公共操作类的原因 很多初学者会奇怪,.Net Framework提供的API相当易用,为何还要多此一举,进行一层封装呢.下面列举封装公共操作类的一些动机. .Net Fr

JDBC公共操作类

import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class DBUtil { public static final String DRIVER = "com.mysql.jdbc.Driver"; public static final