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

  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() {//空值返回nullAssert.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 ) );//可空decimalexpression = 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() {//空值返回nullAssert.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

Util应用程序框架公共操作类(八):Lambda表达式公共操作类(二)相关推荐

  1. C++11 lambda表达式、function类模板、bind函数适配器

    文章目录 lambda表达式 lambda表达式的语法 lambda表达式的原理 function模板 function与重载函数 bind函数适配器 lambda表达式 当我们在写代码的时候如果经常 ...

  2. Java 8:将匿名类转换为Lambda表达式

    将匿名类(实现一种方法)重构为lambda表达式,可使您的代码更简洁明了. 例如,这是Runnable及其lambda等效项的匿名类: // using an anonymous class Runn ...

  3. Lambda表达式实现匿名类

    @cx天王盖地虎 Lambda表达式实现匿名类 比如我们要为控件添加时间监听器,常规的步骤是: 1.创建一个实现了ActionListener接口的内部类,并将其添加到按钮: //按钮控件JButto ...

  4. 【Apache POI】Excel操作(八):Excel工具类的封装(终极版)

    恋爱最珍贵的纪念品,从来就不是那些你送我的手表和项链,甚至也不是那些甜蜜的短信和合照.是你留在我身上的,如同河流留给山川的,那些你对我造成的改变. 有目录,不迷路 前言 代码开整 环境准备 正式开整 ...

  5. 02java进阶03-异常、线程、同步、线程池、Lambda表达式、File类、递归

    目录 一.异常 二.异常的处理 三.自定义异常 四.多线程 五.线程.同步 5.1.线程 5.2同步 5.3线程安全 5.4线程状态 六.等待唤醒机制 6.1 线程间通信 6.2 等待唤醒机制 6.3 ...

  6. 泛型算法(lambda表达式、function类模板、bind函数适配器、迭代器类别、链表数据结构独有的算法)

    文章目录 概念 find()函数 迭代器令算法不依赖于容器 但算法依赖于元素类型的操作 算法永远不会执行容器的操作 只读算法 accumulate()函数 从两个序列中读取元素(equal函数为例) ...

  7. 定制操作(传递函数或lambda表达式)

    很多算法都会比较输入序列中的元素.默认情况下,这类算法使用元素类型的<或==运算符完成比较.标准库还为这些算法定义了额外的版本,允许我们提供自己定义的操作来代替默认运算符. 例如,sort算法默 ...

  8. java 文件路径表达式_Java基础(二十二) Lambda表达式和File类

    函数式编程思想 强调的是做什么,而不是以什么样的方式来做,它忽略了面向对象的复杂语法,只要能够获取到结果,谁去做的,怎么做的,都不重要,重要的是结果,不重视过程. 冗余的Runnable代码 传统的写 ...

  9. 4.File类、Lambda表达式、JAVA IO

    一.File类 File类的每一个实例可以表示硬盘(文件系统)中的一个文件或目录(实际上表示的是一个抽象路径),使用File可以做到: 1:访问其表示的文件或目录的属性信息,例如:名字,大小,修改时间 ...

最新文章

  1. Elastic Search入门:架构说明及Docker方式体验
  2. 用户 'sa' 登录失败。 (Microsoft SQL Server,错误: 18456)
  3. U-Boot顶层Makefile分析
  4. 20个常用的Python小技巧
  5. mysql数据超10亿条,大型主键:超过10亿行MySQL + InnoDB?
  6. CentOS7的安装和配置
  7. 机器学习-决策树(ID3、C4.5、CART)
  8. 哈理工计算机学院学生会技术部,计算机与信息学院学生会简介
  9. linux进入别人电脑,怎么进入别人电脑--局域网【详解】
  10. 远程计算机没反映6678,6678 PCIe 与FPGA LINK UP 后 不能获得FPGA的DEVICE_ID和VENDDR_ID
  11. opencv-python 摄像机标定
  12. 数学建模——更新1——excel箱线图
  13. 简易网页版进程管理器(支持手机管理电脑进程)
  14. 智慧灯杆系统设计架构简介
  15. 8051蜂鸣器程序c语言,单片机有源蜂鸣器试验程序(带电路图)
  16. CSUSTOJ-藤原书记想要探病(简单矩阵快速幂)
  17. oracle 初级学习(王二暖 视频 笔记)
  18. 第四次作业——个人作业——必应词典软件案例分析
  19. request.setattribute详解
  20. 【Data Science from Scratch 学习笔记】第2章 Python速成(上)

热门文章

  1. 揭秘星际2人工智能AlphaStar:DeepMind科学家回应一切
  2. 2018全球硬科技创新暨“一带一路”创新合作大会,这些硬科技都要来!
  3. 价值2950亿美元的「量子霸权」,技术水平到了哪个阶段
  4. 科学家发现新的人类脑细胞,或可解答一个难题
  5. 阿里云发布三大人工智能产品:推动AI产业落地
  6. 贝叶斯网络之父Judea Pearl:要建立真正的人工智能,少不了因果推理
  7. Python 实战多元线性回归模型,附带原理+代码
  8. bzoj2458: [BeiJing2011]最小三角形
  9. 记录opencv编译过程
  10. 当前环境下 物联网的四大关键点