在日,月和年过滤的日期的linq表达式

时间:2015-02-26 17:04:02

标签: c# linq lambda expression

使用EQUAL找不到数据?因为时差? 有人可以告诉我如何为日期创建有效的表达式?

表格

UserId      Username                             DateCreated
466         rebecca.manning@yahoo.com            5/10/1980 5:18:18 AM
467         lauren.oliver@yahoo.com              5/10/1980 5:18:18 AM
502         felicity.stewart@yahoo.com           5/10/1980 5:18:18 AM
534         sebastian.dowd@yahoo.com             5/10/1980 5:18:18 AM
535         nicola.howard@yahoo.com              5/10/1980 5:18:18 AM
570         evan.hodges@yahoo.com                4/10/1980 5:18:18 AM
607         nathan.henderson@yahoo.com           4/10/1980 4:17:17 AM
608         phil.vaughan@yahoo.com               4/10/1980 4:17:17 AM
642         piers.skinner@yahoo.com              4/10/1980 4:17:17 AM
643         julia.ferguson@yahoo.com             4/10/1980 4:17:17 AM

如何为仅在日,月和年过滤的日期创建linq表达式 使用Linq Expression Builder?

我有一个课程" TableExpression.cs "它处理所有过滤器" where fieldname .."," Orders"

而不是过滤

  new Filters{FieldName="DateCreated",FieldValue= new DateTime(1980,10,10),LinqExprOpr = LinqExprOperator.LessThanOrEqual,LinqExprSrt = LinqExprSort.OrderBy,IsSortedField = false},
  new Filters{FieldName="DateCreated",FieldValue= new DateTime(1979,10,10),LinqExprOpr = LinqExprOperator.GreaterThanOrEqual,LinqExprSrt = LinqExprSort.ThenBy,IsSortedField = false}

我希望使用 equal(=)运算符来过滤它。

new Filters{FieldName="DateCreated",FieldValue= new DateTime(1980,10,10),LinqExprOpr = **LinqExprOperator.Equal**,LinqExprSrt = LinqExprSort.OrderBy,IsSortedField = false},

我的动态表达式构建器类

enter code here
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using Common;

namespace DataAccess.Config.TableExpression
{
    public static class ExressionBuilderV3
    {
        public static IQueryable<T> CreateExpressions<T>(IList<Filters> _filters, IQueryable<T> source)
        {
            Type ParmType = typeof(T);
            ParameterExpression ParmExpr = Expression.Parameter(ParmType, ParmType.Name);
            Expression ListOfExpr = null;
            // Condition Query
            foreach (var f in _filters)
            {
                PropertyInfo pInfo = ParmType.GetProperties().Where(_ => _.Name == f.FieldName).FirstOrDefault();
                Type FieldType = Type.GetType(pInfo.PropertyType.FullName);
                if (ListOfExpr == null)
                {
                    ListOfExpr = AddOperatorExpression(ParmExpr, f.FieldName, f.FieldValue, FieldType, f.LinqExprOpr);

                }
                else
                {
                    ListOfExpr = AddBitWiseExpression(ListOfExpr, 
                                                       AddOperatorExpression(ParmExpr, f.FieldName, f.FieldValue, FieldType, f.LinqExprOpr)
                                                     , f.LinqExprBtw);
                }
            }
            // Sort Query
            Expression<Func<T, bool>> ExprTotal = Expression.Lambda<Func<T, bool>>(ListOfExpr, ParmExpr);
            source = source.Where(ExprTotal);
            ListOfExpr = null;
            foreach (var f in _filters)
            {
                PropertyInfo pInfo = ParmType.GetProperties().Where(_ => _.Name == f.FieldName).FirstOrDefault();
                Type FieldType = pInfo.PropertyType;
                //*****************************************************************************************************
                if (f.IsSortedField)
                {
                    source = Sorting(source, ParmType, f.FieldName, f.LinqExprSrt);
                }
                //*****************************************************************************************************
            }
            Filters filter = _filters.SingleOrDefault(_ => _.IsSortedField == true && _.PageSize > 0);
            if (filter != null)
            {
                source = source.Skip((filter.PageIndex -1) * filter.PageSize ).Take(filter.PageSize);
            }
            return source;
        }

        private static Expression AddBitWiseExpression(Expression _Expression1, Expression _Expression2, LinqExprBitWise _LinqExprBitWise) 
        { 
            Expression RtrnExpression = null;
            switch (_LinqExprBitWise)
            {
                case LinqExprBitWise.Or:
                    RtrnExpression = Expression.Or(_Expression1, _Expression2);
                    break;
                case LinqExprBitWise.AndAlso:
                    RtrnExpression = Expression.AndAlso(_Expression1, _Expression2);
                    break;
            }
            return RtrnExpression;
        }

        private static Expression AddOperatorExpression(ParameterExpression _ParmExpr, String _FieldName, object _FieldValue, Type _typeOf, LinqExprOperator _operator)
        {

            Expression FieldName = Expression.Property(_ParmExpr, _FieldName);
            Expression FieldValue = Expression.Constant(_FieldValue, _typeOf);

            Expression rtrnExpr = null;
            #region
            switch (_operator)
            {
                case LinqExprOperator.Equals:
                    rtrnExpr = Expression.Equal(FieldName, FieldValue);
                    break;
                case LinqExprOperator.GreaterThan:
                    rtrnExpr = Expression.GreaterThan(FieldName, FieldValue);
                    break;
                case LinqExprOperator.GreaterThanOrEqual:
                    rtrnExpr = Expression.GreaterThanOrEqual(FieldName, FieldValue);
                    break;
                case LinqExprOperator.LessThan:
                    rtrnExpr = Expression.LessThan(FieldName, FieldValue);
                    break;
                case LinqExprOperator.LessThanOrEqual:
                    rtrnExpr = Expression.LessThanOrEqual(FieldName, FieldValue);
                    break;
                case LinqExprOperator.Contains:
                    rtrnExpr = Expression.Call(FieldName, typeof(string).GetMethod("Contains"), FieldValue);
                    break;
                case LinqExprOperator.StartsWith:
                    rtrnExpr = Expression.Call(FieldName, typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) }), FieldValue);
                    break;
                case LinqExprOperator.EndsWith:
                    rtrnExpr = Expression.Call(FieldName, typeof(string).GetMethod("EndsWith", new Type[] { typeof(string) }), FieldValue);
                    break;
            }
            #endregion
            return rtrnExpr;
        }

        private static IQueryable<T> Sorting<T>(IQueryable<T> _Source, Type _ParmType, String _FieldName, LinqExprSort _LinqExprSort) 
        {
            string orderMethodName = "";
            switch (_LinqExprSort) 
            { 
                case LinqExprSort.OrderBy:
                    orderMethodName = "OrderBy";
                    break;
                case LinqExprSort.OrderByDescending:
                    orderMethodName = "OrderByDescending";
                    break;
                case LinqExprSort.ThenBy:
                    orderMethodName = "ThenBy";
                    break;
                case LinqExprSort.ThenByDescending:
                    orderMethodName = "ThenByDescending";
                    break;
            }

            var param = Expression.Parameter(_ParmType);
            var property = _ParmType.GetProperty(_FieldName);

            return _Source.Provider.CreateQuery<T>(
                Expression.Call(
                    typeof(Queryable),
                    orderMethodName,
                    new Type[] { _ParmType , property.PropertyType },
                    _Source.Expression,
                    Expression.Quote(
                        Expression.Lambda(
                            Expression.Property(param, property),
                            param))
                ));
        }

        /***************************************************************************/
    }
}

1 个答案:

答案 0 :(得分:0)

在这种情况下,您需要的是一种转换方法(Func<DateTime, DateTime>)(x =>{ return x.Date;}),仅为您提供日期部分。如果你看下面我的例子,你会看到,当我有一个转换方法时,我使用Method.Call和转换方法以及适当的表达式作为输入。这样做可以在比较之前转换任何其他类型的对象。

void static Main()
{
    var ops  = new List<Ops>
    { 
        /*new Ops
        {
            OperandType = typeof(string), 
            OpType=OpType.Equals, 
            OperandName = "Name", 
            ValueToCompare = "MM"
        },
        new Ops
        {
            OperandType = typeof(string), 
            OpType=OpType.Equals, 
            OperandName = "ID", 
            ValueToCompare = 1
        },*/
        new Ops
        {
            OperandType = typeof(DateTime), 
            OpType=OpType.Equals, 
            OperandName = "Date", 
            ValueToCompare = new DateTime(2014,12,1),
            //key is this transformation method
            TransformationMethod = ((Func<DateTime, DateTime>)(x =>{ return x.Date;})).Method
        },
    };
    var testClasses = new List<TestClass>
    {
        new TestClass { ID =1, Name = "MM", Date = new DateTime(2014,12,1,2,32,10)},
        new TestClass { ID =2, Name = "BB", Date = new DateTime(2014,12,2)}
    };

    var funct = ExpressionBuilder.BuildExpressions<TestClass>(ops);
    foreach(var item in testClasses.Where(funct))
    {
        Console.WriteLine("ID " +item.ID);
        Console.WriteLine("Name " +item.Name);
        Console.WriteLine("Date" + item.Date);
    }
}

//在此处定义其他方法和类     public enum OpType     {         等于     }

public class Ops
{
    public Type OperandType {get; set;}

    public OpType OpType {get; set;}

    public string OperandName {get;set;}

    public object ValueToCompare {get;set;}

    public MethodInfo TransformationMethod{get;set;}
}

public class TestClass
{   
    public int ID {get;set;}
    public string Name {get; set;}
    public DateTime Date {get;set;}
}

public class ExpressionBuilder
{
    public static Func<T,bool> BuildExpressions<T>( List<Ops> opList)
    {
        Expression currentExpression= null;
        var parameter = Expression.Parameter(typeof(T), "prop");
        for(int i =0; i< opList.Count; i++)
        {
            var op =  opList[i];
            Expression innerExpression = null;
            switch(op.OpType)
            {
                case OpType.Equals :
                {
                    var innerParameter = Expression.Property(parameter,op.OperandName);
                    //Console.WriteLine(innerParameter);
                    var ConstExpression = Expression.Constant(op.ValueToCompare);
                    //Console.WriteLine(ConstExpression);
                    if(op.TransformationMethod != null)
                    {
                        innerExpression = Expression.Equal(Expression.Call(op.TransformationMethod, new []{innerParameter}), 
                                                           Expression.Call(op.TransformationMethod, new []{ConstExpression}));
                        //Console.WriteLine(innerExpression);
                    }
                    else
                        innerExpression = Expression.Equal(innerParameter, ConstExpression);
                    break;
                }
            }

            if (i >0)
            {
                currentExpression = Expression.And(currentExpression, innerExpression);
            }
            else
            {
                currentExpression = innerExpression;
            }
        }
        var lambdaExpression = Expression.Lambda<Func<T,bool>>(currentExpression, new []{parameter});
        //Console.WriteLine(lambdaExpression);
        return lambdaExpression.Compile() ;
    }
}