zoukankan      html  css  js  c++  java
  • Util应用程序框架公共操作类(八):Lambda表达式公共操作类(二)

      前面介绍了查询的基础扩展,下面准备给大家介绍一些有用的查询封装手法,比如对日期范围查询,数值范围查询的封装等,为了支持这些功能,需要增强公共操作类。

      Lambda表达式公共操作类,我在前面已经简单介绍过,要么从Lambda表达式中获取信息,要么动态创建Lambda表达式,本篇直接贴代码,如果发现有些代码与以前不同,原因有二,一是之前还未用到,只发了部分代码,二是可能代码已重构。需要说明的一点是,我不会考虑代码兼容性,API命名随时可能修改,如果你直接将本系列的代码用到你的项目上要格外注意。

      修改Util项目的Lambda类,代码如下。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Reflection;
    using DynamicExpression = Util.Lambdas.Dynamics.DynamicExpression;
    
    namespace Util {
        /// <summary>
        /// Lambda表达式操作
        /// </summary>
        public class Lambda {
    
            #region GetName(获取成员名称)
    
            /// <summary>
            /// 获取成员名称,范例:t => t.Name,返回 Name
            /// </summary>
            /// <param name="expression">表达式,范例:t => t.Name</param>
            public static string GetName( LambdaExpression expression ) {
                var memberExpression = GetMemberExpression( expression );
                if ( memberExpression == null )
                    return string.Empty;
                string result = memberExpression.ToString();
                return result.Substring( result.IndexOf( ".", StringComparison.Ordinal ) + 1 );
            }
    
            /// <summary>
            /// 获取成员表达式
            /// </summary>
            private static MemberExpression GetMemberExpression( LambdaExpression expression ) {
                if ( expression == null )
                    return null;
                var unaryExpression = expression.Body as UnaryExpression;
                if ( unaryExpression == null )
                    return expression.Body as MemberExpression;
                return unaryExpression.Operand as MemberExpression;
            }
    
            #endregion
    
            #region GetMember(获取成员)
    
            /// <summary>
            /// 获取成员
            /// </summary>
            /// <param name="expression">表达式,范例:t => t.Name</param>
            public static MemberInfo GetMember( LambdaExpression expression ) {
                var memberExpression = GetMemberExpression( expression );
                if ( memberExpression == null )
                    return null;
                return memberExpression.Member;
            }
    
            #endregion
    
            #region GetValue(获取值)
    
            /// <summary>
            /// 获取值,范例:t => t.Name == "A",返回 A
            /// </summary>
            /// <param name="expression">表达式,范例:t => t.Name == "A"</param>
            public static object GetValue( LambdaExpression expression ) {
                if ( expression == null )
                    return null;
                var memberExpression = expression.Body as MemberExpression;
                if ( memberExpression != null )
                    return GetMemberValue( memberExpression );
                BinaryExpression binaryExpression = GetBinaryExpression( expression );
                if ( binaryExpression != null )
                    return GetBinaryValue( binaryExpression );
                var callExpression = expression.Body as MethodCallExpression;
                if ( callExpression != null )
                    return GetMethodValue( callExpression );
                return null;
            }
    
            /// <summary>
            /// 获取二元表达式
            /// </summary>
            private static BinaryExpression GetBinaryExpression( LambdaExpression expression ) {
                var binaryExpression = expression.Body as BinaryExpression;
                if ( binaryExpression != null )
                    return binaryExpression;
                var unaryExpression = expression.Body as UnaryExpression;
                if ( unaryExpression == null )
                    return null;
                return unaryExpression.Operand as BinaryExpression;
            }
    
            /// <summary>
            /// 获取二元表达式的值
            /// </summary>
            private static object GetBinaryValue( BinaryExpression binaryExpression ) {
                var unaryExpression = binaryExpression.Right as UnaryExpression;
                if ( unaryExpression != null )
                    return GetConstantValue( unaryExpression.Operand );
                var memberExpression = binaryExpression.Right as MemberExpression;
                if ( memberExpression != null )
                    return GetMemberValue( memberExpression );
                return GetConstantValue( binaryExpression.Right );
            }
    
            /// <summary>
            /// 获取属性表达式的值
            /// </summary>
            private static object GetMemberValue( MemberExpression expression ) {
                if ( expression == null )
                    return null;
                var field = expression.Member as FieldInfo;
                if ( field != null ) {
                    var constValue = GetConstantValue( expression.Expression );
                    return field.GetValue( constValue );
                }
                var property = expression.Member as PropertyInfo;
                if ( property == null )
                    return null;
                var value = GetMemberValue( expression.Expression as MemberExpression );
                return property.GetValue( value );
            }
    
            /// <summary>
            /// 获取常量值
            /// </summary>
            private static object GetConstantValue( Expression expression ) {
                var constantExpression = expression as ConstantExpression;
                if ( constantExpression == null )
                    return null;
                return constantExpression.Value;
            }
    
            /// <summary>
            /// 获取方法调用表达式的值
            /// </summary>
            private static object GetMethodValue( MethodCallExpression callExpression ) {
                var argumentExpression = callExpression.Arguments.FirstOrDefault();
                var memberExpression = argumentExpression as MemberExpression;
                if ( memberExpression != null )
                    return GetMemberValue( memberExpression );
                return GetConstantValue( argumentExpression );
            }
    
            #endregion
    
            #region GetParameter(获取参数)
    
            /// <summary>
            /// 获取参数,范例:t.Name,返回 t
            /// </summary>
            /// <param name="expression">表达式,范例:t.Name</param>
            public static ParameterExpression GetParameter( LambdaExpression expression ) {
                if ( expression == null )
                    return null;
                BinaryExpression binaryExpression = GetBinaryExpression( expression );
                if ( binaryExpression == null )
                    return null;
                return GetParameterByMember( binaryExpression.Left );
            }
    
            /// <summary>
            /// 递归获取参数
            /// </summary>
            private static ParameterExpression GetParameterByMember( Expression expression ) {
                if ( expression == null )
                    return null;
                ParameterExpression result = expression as ParameterExpression;
                if ( result != null )
                    return result;
                MemberExpression memberExpression = expression as MemberExpression;
                if ( memberExpression == null )
                    return null;
                return GetParameterByMember( memberExpression.Expression );
            }
    
            #endregion
    
            #region GetAttribute(获取特性)
    
            /// <summary>
            /// 获取特性
            /// </summary>
            /// <typeparam name="TEntity">实体类型</typeparam>
            /// <typeparam name="TProperty">属性类型</typeparam>
            /// <typeparam name="TAttribute">特性类型</typeparam>
            /// <param name="propertyExpression">属性表达式</param>
            public static TAttribute GetAttribute<TEntity, TProperty, TAttribute>( Expression<Func<TEntity, TProperty>> propertyExpression )
                where TAttribute : Attribute {
                var memberInfo = GetMember( propertyExpression );
                return memberInfo.GetCustomAttribute<TAttribute>();
            }
    
            #endregion
    
            #region GetAttributes(获取特性列表)
    
            /// <summary>
            /// 获取特性列表
            /// </summary>
            /// <typeparam name="TEntity">实体类型</typeparam>
            /// <typeparam name="TProperty">属性类型</typeparam>
            /// <typeparam name="TAttribute">特性类型</typeparam>
            /// <param name="propertyExpression">属性表达式</param>
            public static IEnumerable<TAttribute> GetAttributes<TEntity, TProperty, TAttribute>( Expression<Func<TEntity, TProperty>> propertyExpression ) where TAttribute : Attribute {
                var memberInfo = GetMember( propertyExpression );
                return memberInfo.GetCustomAttributes<TAttribute>();
            }
    
            #endregion
    
            #region Constant(获取常量)
    
            /// <summary>
            /// 获取常量表达式,自动转换值的类型
            /// </summary>
            /// <param name="expression">表达式</param>
            /// <param name="value"></param>
            public static ConstantExpression Constant( Expression expression, object value ) {
                var memberExpression = expression as MemberExpression;
                if ( memberExpression == null )
                    return Expression.Constant( value );
                return Expression.Constant( value, memberExpression.Type );
            }
    
            #endregion
    
            #region GetCriteriaCount(获取谓词条件的个数)
    
            /// <summary>
            /// 获取谓词条件的个数
            /// </summary>
            /// <param name="expression">谓词表达式,范例:t => t.Name == "A"</param>
            public static int GetCriteriaCount( LambdaExpression expression ) {
                if ( expression == null )
                    return 0;
                var result = expression.ToString().Replace( "AndAlso", "|" ).Replace( "OrElse", "|" );
                return result.Split( '|' ).Count();
            }
    
            #endregion
    
            #region Equal(等于表达式)
    
            /// <summary>
            /// 创建等于运算lambda表达式
            /// </summary>
            /// <typeparam name="T">对象类型</typeparam>
            /// <param name="propertyName">属性名</param>
            /// <param name="value"></param>
            public static Expression<Func<T, bool>> Equal<T>( string propertyName, object value ) {
                var parameter = CreateParameter<T>();
                return parameter.Property( propertyName )
                        .Equal( value )
                        .ToLambda<Func<T, bool>>( parameter );
            }
    
            /// <summary>
            /// 创建参数
            /// </summary>
            private static ParameterExpression CreateParameter<T>() {
                return Expression.Parameter( typeof( T ), "t" );
            }
    
            #endregion
    
            #region NotEqual(不等于表达式)
    
            /// <summary>
            /// 创建不等于运算lambda表达式
            /// </summary>
            /// <typeparam name="T">对象类型</typeparam>
            /// <param name="propertyName">属性名</param>
            /// <param name="value"></param>
            public static Expression<Func<T, bool>> NotEqual<T>( string propertyName, object value ) {
                var parameter = CreateParameter<T>();
                return parameter.Property( propertyName )
                        .NotEqual( value )
                        .ToLambda<Func<T, bool>>( parameter );
            }
    
            #endregion
    
            #region Greater(大于表达式)
    
            /// <summary>
            /// 创建大于运算lambda表达式
            /// </summary>
            /// <typeparam name="T">对象类型</typeparam>
            /// <param name="propertyName">属性名</param>
            /// <param name="value"></param>
            public static Expression<Func<T, bool>> Greater<T>( string propertyName, object value ) {
                var parameter = CreateParameter<T>();
                return parameter.Property( propertyName )
                        .Greater( value )
                        .ToLambda<Func<T, bool>>( parameter );
            }
    
            #endregion
    
            #region Less(小于表达式)
    
            /// <summary>
            /// 创建小于运算lambda表达式
            /// </summary>
            /// <typeparam name="T">对象类型</typeparam>
            /// <param name="propertyName">属性名</param>
            /// <param name="value"></param>
            public static Expression<Func<T, bool>> Less<T>( string propertyName, object value ) {
                var parameter = CreateParameter<T>();
                return parameter.Property( propertyName )
                        .Less( value )
                        .ToLambda<Func<T, bool>>( parameter );
            }
    
            #endregion
    
            #region GreaterEqual(大于等于表达式)
    
            /// <summary>
            /// 创建大于等于运算lambda表达式
            /// </summary>
            /// <typeparam name="T">对象类型</typeparam>
            /// <param name="propertyName">属性名</param>
            /// <param name="value"></param>
            public static Expression<Func<T, bool>> GreaterEqual<T>( string propertyName, object value ) {
                var parameter = CreateParameter<T>();
                return parameter.Property( propertyName )
                        .GreaterEqual( value )
                        .ToLambda<Func<T, bool>>( parameter );
            }
    
            #endregion
    
            #region LessEqual(小于等于表达式)
    
            /// <summary>
            /// 创建小于等于运算lambda表达式
            /// </summary>
            /// <typeparam name="T">对象类型</typeparam>
            /// <param name="propertyName">属性名</param>
            /// <param name="value"></param>
            public static Expression<Func<T, bool>> LessEqual<T>( string propertyName, object value ) {
                var parameter = CreateParameter<T>();
                return parameter.Property( propertyName )
                        .LessEqual( value )
                        .ToLambda<Func<T, bool>>( parameter );
            }
    
            #endregion
    
            #region Contains(调用Contains方法)
    
            /// <summary>
            /// 调用Contains方法
            /// </summary>
            /// <typeparam name="T">对象类型</typeparam>
            /// <param name="propertyName">属性名</param>
            /// <param name="value"></param>
            public static Expression<Func<T, bool>> Contains<T>( string propertyName, object value ) {
                return Call<T>( propertyName, "Contains", value );
            }
    
            /// <summary>
            /// 调用方法
            /// </summary>
            private static Expression<Func<T, bool>> Call<T>( string propertyName, string methodName, object value ) {
                var parameter = CreateParameter<T>();
                return parameter.Property( propertyName )
                    .Call( methodName, value )
                    .ToLambda<Func<T, bool>>( parameter );
            }
    
            #endregion
    
            #region Starts(调用StartsWith方法)
    
            /// <summary>
            /// 调用StartsWith方法
            /// </summary>
            /// <typeparam name="T">对象类型</typeparam>
            /// <param name="propertyName">属性名</param>
            /// <param name="value"></param>
            public static Expression<Func<T, bool>> Starts<T>( string propertyName, string value ) {
                var parameter = CreateParameter<T>();
                var property = parameter.Property( propertyName );
                var call = Expression.Call( property, property.Type.GetMethod( "StartsWith", new Type[] { typeof( string ) } ),
                    Expression.Constant( value ) );
                return call.ToLambda<Func<T, bool>>( parameter );
            }
    
            #endregion
    
            #region Ends(调用EndsWith方法)
    
            /// <summary>
            /// 调用EndsWith方法
            /// </summary>
            /// <typeparam name="T">对象类型</typeparam>
            /// <param name="propertyName">属性名</param>
            /// <param name="value"></param>
            public static Expression<Func<T, bool>> Ends<T>( string propertyName, string value ) {
                var parameter = CreateParameter<T>();
                var property = parameter.Property( propertyName );
                var call = Expression.Call( property, property.Type.GetMethod( "EndsWith", new Type[] { typeof( string ) } ),
                    Expression.Constant( value ) );
                return call.ToLambda<Func<T, bool>>( parameter );
            }
    
            #endregion
    
            #region ParsePredicate(解析为谓词表达式)
    
            /// <summary>
            /// 解析为谓词表达式
            /// </summary>
            /// <typeparam name="T">实体类型</typeparam>
            /// <param name="propertyName">属性名</param>
            /// <param name="value"></param>
            /// <param name="operator">运算符</param>
            public static Expression<Func<T, bool>> ParsePredicate<T>( string propertyName, object value, Operator @operator ) {
                var parameter = Expression.Parameter( typeof( T ), "t" );
                return parameter.Property( propertyName ).Operation( @operator, value ).ToLambda<Func<T, bool>>( parameter );
            }
    
            /// <summary>
            /// 解析为谓词表达式
            /// </summary>
            /// <typeparam name="T">实体类型</typeparam>
            /// <param name="predicateExpression">谓词表达式字符串,参数占位符为@0,@1,@2 ...</param>
            /// <param name="values"></param>
            public static Expression<Func<T, bool>> ParsePredicate<T>( string predicateExpression, params object[] values ) {
                return DynamicExpression.ParseLambda( typeof( T ), typeof( bool ), predicateExpression, values ) as Expression<Func<T, bool>>;
            }
    
            #endregion
        }
    }

      在Util.Tests单元测试项目新建两个测试样例,代码如下。

    using System.ComponentModel.DataAnnotations;
    
    namespace Util.Tests.Samples {
        /// <summary>
        /// 测试1
        /// </summary>
        public class Test1 {
            [StringLength( 20, ErrorMessage = "长度不能超过20" )]
            [Required( ErrorMessage = "名称不能为空" )]
            [Display( Name = "名称" )]
            public string Name { get; set; }
            public int Age { get; set; }
            public int? NullableInt { get; set; }
            public decimal? NullableDecimal { get; set; }
            public TestA A { get; set; }
            public class TestA {
                public int Integer { get; set; }
                public string Address { get; set; }
                public TestB B { get; set; }
                public class TestB {
                    public string Name { get; set; }
                }
            }
        }
    }
    
    
    using System;
    using System.ComponentModel.DataAnnotations;
    
    namespace Util.Tests.Samples {
        /// <summary>
        /// 测试2
        /// </summary>
        [Serializable]
        public class Test2 {
            public Test2() {
            }
            public Test2( string name ) {
                Name = name;
            }
    
            [Required(ErrorMessage = "名称不能为空")]
            public string Name { get; set; }
            public int Int { get; set; }
            public int? NullableInt { get; set; }
            public decimal? NullableDecimal { get; set; }
            public decimal Decimal { get; set; }
            public TestA A { get; set; }
            [Serializable]
            public class TestA {
                public int Integer { get; set; }
                public string Address { get; set; }
                public TestB B { get; set; }
                public class TestB {
                    public string Name { get; set; }
                }
            }
        }
    }

      修改Util.Tests单元测试项目LambdaTest单元测试,代码如下。

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.Linq.Expressions;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using Util.Tests.Samples;
    
    namespace Util.Tests {
        /// <summary>
        /// 表达式测试
        /// </summary>
        [TestClass]
        public class LambdaTest {
    
            #region GetName(获取成员名称)
    
            /// <summary>
            /// 获取成员名称
            /// </summary>
            [TestMethod]
            public void TestGetName() {
                //空值返回空字符串
                Assert.AreEqual( "", Lambda.GetName( null ) );
    
                //返回一级属性名
                Expression<Func<Test1, string>> expression = test => test.Name;
                Assert.AreEqual( "Name", Lambda.GetName( expression ) );
    
                //返回二级属性名
                Expression<Func<Test1, string>> expression2 = test => test.A.Address;
                Assert.AreEqual( "A.Address", Lambda.GetName( expression2 ) );
    
                //返回三级属性名
                Expression<Func<Test1, string>> expression3 = test => test.A.B.Name;
                Assert.AreEqual( "A.B.Name", Lambda.GetName( expression3 ) );
    
                //测试可空整型
                Expression<Func<Test1, int?>> expression4 = test => test.NullableInt;
                Assert.AreEqual( "NullableInt", Lambda.GetName( expression4 ) );
    
                //测试类型转换
                Expression<Func<Test1, int?>> expression5 = test => test.Age;
                Assert.AreEqual( "Age", Lambda.GetName( expression5 ) );
            }
    
            #endregion
    
            #region GetValue(获取成员值)
    
            /// <summary>
            /// 获取成员值,委托返回类型为Object
            /// </summary>
            [TestMethod]
            public void TestGetValue_Object() {
                Expression<Func<Test1, object>> expression = test => test.Name == "A";
                Assert.AreEqual( "A", Lambda.GetValue( expression ) );
            }
    
            /// <summary>
            /// 获取成员值,委托返回类型为bool
            /// </summary>
            [TestMethod]
            public void TestGetValue_Boolean() {
                //空值返回null
                Assert.AreEqual( null, Lambda.GetValue( null ) );
    
                //一级返回值
                Expression<Func<Test1, bool>> expression = test => test.Name == "A";
                Assert.AreEqual( "A", Lambda.GetValue( expression ) );
    
                //二级返回值
                Expression<Func<Test1, bool>> expression2 = test => test.A.Integer == 1;
                Assert.AreEqual( 1, Lambda.GetValue( expression2 ) );
    
                //三级返回值
                Expression<Func<Test1, bool>> expression3 = test => test.A.B.Name == "B";
                Assert.AreEqual( "B", Lambda.GetValue( expression3 ) );
            }
    
            /// <summary>
            /// 获取可空类型的值
            /// </summary>
            [TestMethod]
            public void TestGetValue_Nullable() {
                //可空整型
                Expression<Func<Test1, bool>> expression = test => test.NullableInt == 1;
                Assert.AreEqual( 1, Lambda.GetValue( expression ) );
    
                //可空decimal
                expression = test => test.NullableDecimal == 1.5M;
                Assert.AreEqual( 1.5M, Lambda.GetValue( expression ) );
            }
    
            /// <summary>
            /// 获取成员值,运算符为方法
            /// </summary>
            [TestMethod]
            public void TestGetValue_Method() {
                //1级返回值
                Expression<Func<Test1, bool>> expression = t => t.Name.Contains( "A" );
                Assert.AreEqual( "A", Lambda.GetValue( expression ) );
    
                //二级返回值
                expression = t => t.A.Address.Contains( "B" );
                Assert.AreEqual( "B", Lambda.GetValue( expression ) );
    
                //三级返回值
                expression = t => t.A.B.Name.StartsWith( "C" );
                Assert.AreEqual( "C", Lambda.GetValue( expression ) );
            }
    
            /// <summary>
            /// 从实例中获取值
            /// </summary>
            [TestMethod]
            public void TestGetValue_Instance() {
                var test = new Test1() { Name = "a", A = new Test1.TestA() { Address = "b", B = new Test1.TestA.TestB() { Name = "c" } } };
    
                //一级属性
                Expression<Func<string>> expression = () => test.Name;
                Assert.AreEqual( "a", Lambda.GetValue( expression ) );
    
                //二级属性
                Expression<Func<string>> expression2 = () => test.A.Address;
                Assert.AreEqual( "b", Lambda.GetValue( expression2 ) );
    
                //三级属性
                Expression<Func<string>> expression3 = () => test.A.B.Name;
                Assert.AreEqual( "c", Lambda.GetValue( expression3 ) );
            }
    
            /// <summary>
            /// 测试值为复杂类型
            /// </summary>
            [TestMethod]
            public void TestGetValue_Complex() {
                var test = new Test1() { Name = "a", A = new Test1.TestA() { Address = "b" } };
    
                //获取表达式的值
                Expression<Func<Test1, bool>> expression = t => t.Name == test.Name;
                Assert.AreEqual( "a", Lambda.GetValue( expression ), "==test.Name" );
                Expression<Func<Test1, bool>> expression2 = t => t.Name == test.A.Address;
                Assert.AreEqual( "b", Lambda.GetValue( expression2 ), "==test.A.Address" );
    
                //获取方法的值
                Expression<Func<Test1, bool>> expression3 = t => t.Name.Contains( test.Name );
                Assert.AreEqual( "a", Lambda.GetValue( expression3 ), "Contains test.Name" );
                Expression<Func<Test1, bool>> expression4 = t => t.Name.Contains( test.A.Address );
                Assert.AreEqual( "b", Lambda.GetValue( expression4 ), "==test.A.Address" );
            }
    
            #endregion
    
            #region GetParameter(获取参数)
    
            /// <summary>
            /// 获取参数
            /// </summary>
            [TestMethod]
            public void TestGetParameter() {
                //空值返回null
                Assert.AreEqual( null, Lambda.GetParameter( null ) );
    
                //一级返回值
                Expression<Func<Test1, object>> expression = test => test.Name == "A";
                Assert.AreEqual( "test", Lambda.GetParameter( expression ).ToString() );
    
                //二级返回值
                Expression<Func<Test1, object>> expression2 = test => test.A.Integer == 1;
                Assert.AreEqual( "test", Lambda.GetParameter( expression2 ).ToString() );
    
                //三级返回值
                Expression<Func<Test1, object>> expression3 = test => test.A.B.Name == "B";
                Assert.AreEqual( "test", Lambda.GetParameter( expression3 ).ToString() );
            }
    
            #endregion
    
            #region GetCriteriaCount(获取谓词条件的个数)
    
            /// <summary>
            /// 获取谓词条件的个数
            /// </summary>
            [TestMethod]
            public void TestGetCriteriaCount() {
                //0个条件
                Assert.AreEqual( 0, Lambda.GetCriteriaCount( null ) );
    
                //1个条件
                Expression<Func<Test1, bool>> expression = test => test.Name == "A";
                Assert.AreEqual( 1, Lambda.GetCriteriaCount( expression ) );
    
                //2个条件,与连接符
                expression = test => test.Name == "A" && test.Name == "B";
                Assert.AreEqual( 2, Lambda.GetCriteriaCount( expression ) );
    
                //2个条件,或连接符
                expression = test => test.Name == "A" || test.Name == "B";
                Assert.AreEqual( 2, Lambda.GetCriteriaCount( expression ) );
    
                //3个条件
                expression = test => test.Name == "A" && test.Name == "B" || test.Name == "C";
                Assert.AreEqual( 3, Lambda.GetCriteriaCount( expression ) );
    
                //3个条件,包括导航属性
                expression = test => test.A.Address == "A" && test.Name == "B" || test.Name == "C";
                Assert.AreEqual( 3, Lambda.GetCriteriaCount( expression ) );
            }
    
            /// <summary>
            /// 获取谓词条件的个数,运算符为方法
            /// </summary>
            [TestMethod]
            public void TestGetCriteriaCount_Method() {
                //1个条件
                Expression<Func<Test1, bool>> expression = t => t.Name.Contains( "A" );
                Assert.AreEqual( 1, Lambda.GetCriteriaCount( expression ) );
    
                //2个条件,与连接
                expression = t => t.Name.Contains( "A" ) && t.Name == "A";
                Assert.AreEqual( 2, Lambda.GetCriteriaCount( expression ) );
    
                //2个条件,或连接,包含导航属性
                expression = t => t.Name.Contains( "A" ) || t.A.Address == "A";
                Assert.AreEqual( 2, Lambda.GetCriteriaCount( expression ) );
            }
    
            #endregion
    
            #region Equal(创建等于表达式)
    
            /// <summary>
            /// 创建等于表达式
            /// </summary>
            [TestMethod]
            public void TestEqual() {
                //一级属性
                Expression<Func<Test1, bool>> expected = t => t.Age == 1;
                Assert.AreEqual( expected.ToString(), Lambda.Equal<Test1>( "Age", 1 ).ToString() );
    
                //二级属性
                Expression<Func<Test1, bool>> expected2 = t => t.A.Integer == 1;
                Assert.AreEqual( expected2.ToString(), Lambda.Equal<Test1>( "A.Integer", 1 ).ToString() );
            }
    
            #endregion
    
            #region NotEqual(创建不等于表达式)
    
            /// <summary>
            /// 创建不等于表达式
            /// </summary>
            [TestMethod]
            public void TestNotEqual() {
                //一级属性
                Expression<Func<Test1, bool>> expected = t => t.Age != 1;
                Assert.AreEqual( expected.ToString(), Lambda.NotEqual<Test1>( "Age", 1 ).ToString() );
    
                //二级属性
                Expression<Func<Test1, bool>> expected2 = t => t.A.Integer != 1;
                Assert.AreEqual( expected2.ToString(), Lambda.NotEqual<Test1>( "A.Integer", 1 ).ToString() );
            }
    
            #endregion
    
            #region Greater(创建大于表达式)
    
            /// <summary>
            /// 创建大于表达式
            /// </summary>
            [TestMethod]
            public void TestGreater() {
                //一级属性
                Expression<Func<Test1, bool>> expected = t => t.Age > 1;
                Assert.AreEqual( expected.ToString(), Lambda.Greater<Test1>( "Age", 1 ).ToString() );
    
                //二级属性
                Expression<Func<Test1, bool>> expected2 = t => t.A.Integer > 1;
                Assert.AreEqual( expected2.ToString(), Lambda.Greater<Test1>( "A.Integer", 1 ).ToString() );
            }
    
            #endregion
    
            #region Less(创建小于表达式)
    
            /// <summary>
            /// 创建小于表达式
            /// </summary>
            [TestMethod]
            public void TestLess() {
                //一级属性
                Expression<Func<Test1, bool>> expected = t => t.Age < 1;
                Assert.AreEqual( expected.ToString(), Lambda.Less<Test1>( "Age", 1 ).ToString() );
    
                //二级属性
                Expression<Func<Test1, bool>> expected2 = t => t.A.Integer < 1;
                Assert.AreEqual( expected2.ToString(), Lambda.Less<Test1>( "A.Integer", 1 ).ToString() );
            }
    
            #endregion
    
            #region GreaterEqual(创建大于等于表达式)
    
            /// <summary>
            /// 创建大于等于表达式
            /// </summary>
            [TestMethod]
            public void TestGreaterEqual() {
                //一级属性
                Expression<Func<Test1, bool>> expected = t => t.Age >= 1;
                Assert.AreEqual( expected.ToString(), Lambda.GreaterEqual<Test1>( "Age", 1 ).ToString() );
    
                //二级属性
                Expression<Func<Test1, bool>> expected2 = t => t.A.Integer >= 1;
                Assert.AreEqual( expected2.ToString(), Lambda.GreaterEqual<Test1>( "A.Integer", 1 ).ToString() );
            }
    
            #endregion
    
            #region LessEqual(创建小于等于表达式)
    
            /// <summary>
            /// 创建小于等于表达式
            /// </summary>
            [TestMethod]
            public void TestLessEqual() {
                //一级属性
                Expression<Func<Test1, bool>> expected = t => t.Age <= 1;
                Assert.AreEqual( expected.ToString(), Lambda.LessEqual<Test1>( "Age", 1 ).ToString() );
    
                //二级属性
                Expression<Func<Test1, bool>> expected2 = t => t.A.Integer <= 1;
                Assert.AreEqual( expected2.ToString(), Lambda.LessEqual<Test1>( "A.Integer", 1 ).ToString() );
            }
    
            #endregion
    
            #region Contains(调用Contains方法)
    
            /// <summary>
            /// 调用Contains方法
            /// </summary>
            [TestMethod]
            public void TestContains() {
                //一级属性
                Expression<Func<Test1, bool>> expected = t => t.Name.Contains( "A" );
                Assert.AreEqual( expected.ToString(), Lambda.Contains<Test1>( "Name", "A" ).ToString() );
    
                //二级属性
                Expression<Func<Test1, bool>> expected2 = t => t.A.Address.Contains( "A" );
                Assert.AreEqual( expected2.ToString(), Lambda.Contains<Test1>( "A.Address", "A" ).ToString() );
    
                //三级属性
                Expression<Func<Test1, bool>> expected3 = t => t.A.B.Name.Contains( "A" );
                Assert.AreEqual( expected3.ToString(), Lambda.Contains<Test1>( "A.B.Name", "A" ).ToString() );
            }
    
            #endregion
    
            #region Starts(调用StartsWith方法)
    
            /// <summary>
            /// 调用StartsWith方法
            /// </summary>
            [TestMethod]
            public void TestStarts() {
                //一级属性
                Expression<Func<Test1, bool>> expected = t => t.Name.StartsWith( "A" );
                Assert.AreEqual( expected.ToString(), Lambda.Starts<Test1>( "Name", "A" ).ToString() );
    
                //二级属性
                Expression<Func<Test1, bool>> expected2 = t => t.A.Address.StartsWith( "A" );
                Assert.AreEqual( expected2.ToString(), Lambda.Starts<Test1>( "A.Address", "A" ).ToString() );
    
                //三级属性
                Expression<Func<Test1, bool>> expected3 = t => t.A.B.Name.StartsWith( "A" );
                Assert.AreEqual( expected3.ToString(), Lambda.Starts<Test1>( "A.B.Name", "A" ).ToString() );
            }
    
            #endregion
    
            #region Ends(调用EndsWith方法)
    
            /// <summary>
            /// 调用EndsWith方法
            /// </summary>
            [TestMethod]
            public void TestEnds() {
                //一级属性
                Expression<Func<Test1, bool>> expected = t => t.Name.EndsWith( "A" );
                Assert.AreEqual( expected.ToString(), Lambda.Ends<Test1>( "Name", "A" ).ToString() );
    
                //二级属性
                Expression<Func<Test1, bool>> expected2 = t => t.A.Address.EndsWith( "A" );
                Assert.AreEqual( expected2.ToString(), Lambda.Ends<Test1>( "A.Address", "A" ).ToString() );
    
                //三级属性
                Expression<Func<Test1, bool>> expected3 = t => t.A.B.Name.EndsWith( "A" );
                Assert.AreEqual( expected3.ToString(), Lambda.Ends<Test1>( "A.B.Name", "A" ).ToString() );
            }
    
            #endregion
    
            #region GetConst(获取常量表达式)
    
            /// <summary>
            /// 获取常量表达式
            /// </summary>
            [TestMethod]
            public void TestGetConst() {
                Expression<Func<Test1, int?>> property = t => t.NullableInt;
                ConstantExpression constantExpression = Lambda.Constant( property, 1 );
                Assert.AreEqual( typeof( int ), constantExpression.Type );
            }
    
            #endregion
    
            #region GetAttribute(获取特性)
    
            /// <summary>
            /// 测试获取特性
            /// </summary>
            [TestMethod]
            public void TestGetAttribute() {
                DisplayAttribute attribute = Lambda.GetAttribute<Test1, string, DisplayAttribute>( t => t.Name );
                Assert.AreEqual( "名称", attribute.Name );
            }
    
            #endregion
    
            #region GetAttributes(获取特性列表)
    
            /// <summary>
            /// 测试获取特性列表
            /// </summary>
            [TestMethod]
            public void TestGetAttributes() {
                IEnumerable<ValidationAttribute> attributes = Lambda.GetAttributes<Test1, string, ValidationAttribute>( t => t.Name );
                Assert.AreEqual( 2, attributes.Count() );
            }
    
            #endregion
        }
    }

      这些操作方法的作用,大家自己看下测试就明白了,具体应用在后面介绍。

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

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

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

  • 相关阅读:
    hdu 2275数据结构水题
    咨询工具、模型、方法论学习笔记 序
    DevExpress DXperience XtraTreeview 如何获取当前光标所在位置的 Node
    Delphi 各个编译版本的开关值
    把对象序列化到文件中和从文件中反序列化的管理类
    Advantech 硬件控制卡的 c# 接口函数
    Delphi 中的 TTimer 和 .NET Framework 中的 Timer 的计时周期研究
    C#设计模式编程之抽象工厂模式新解
    敏捷开发
    关于HTML静态页面(含自动分页)生成的可行性方案
  • 原文地址:https://www.cnblogs.com/xiadao521/p/4206696.html
Copyright © 2011-2022 走看看