2015-06-12 3 views
1

Я нашел ответы для аналогичной концепции, но ни один из них, похоже, не соответствует моему делу.Анализ Дата Дата DateTime с двоичным выражением

Я создаю объект, который фильтрует результаты с помощью предложения Where и Lambda для типов, известных во время выполнения.

Массив фильтра может содержать один или несколько фильтров с именем свойства и оператором равенства (т. Е. Gte, eq, neq и т. Д.) И значением для сравнения.

Так как у меня могло быть более одного свойства для фильтрации, я сначала захватил все BinaryExpression, которые мне нужно сравнить с любым свойством объекта и объединить их в одном выражении, которое передается в запрос Where where.

Если тип свойства фильтра - DateTime, я хочу сравнить только часть даты свойства с помощью BinaryExpression.

У меня есть метод, который получает имя параметра фильтра и его значение.

public static Expression<Func<T, bool>> GetEqualExpression<T>(string parameterName, 
      string comparisonValue) { 

    var param = Expression.Parameter(typeof(T), parameterName); 
    var property = Expression.Property(param, parameterName); 

    var propInfo = (PropertyInfo) property.Member; 
    var propType = propInfo.PropertyType; 

    if (propType == typeof(DateTime)) { 

     // Parse the string to a DateTime. 
     const string dateFormat = "ddd MMM d yyyy HH:mm:ss 'GMT'K"; 
     var parsedDate = DateTime.ParseExact(comparisonValue, dateFormat, CultureInfo.InvariantCulture); 

     // Trying to access the 'Date' child property. 
     property = Expression.Property(property, "Date"); 
     var constant = Expression.Constant(parsedDate.Date); 


     return Expression.Lambda<Func<T, bool>>(Expression.Equal(property, constant), param); 
    } 

    ... 
} 

учетом, например объект как:

public class Ticket { 
    public DateTime StartDate {get; set;} 
    public DateTime DueDate {get; set;} 
} 

и фильтр для имущества «STARTDATE», когда я прохожу выражение «параметра лямбда в запросе, где положение, он терпит неудачу с исключением не в области.";

Что мне не хватает?

Заранее спасибо.

Update

Таким образом, благодаря xanatos я обнаружил, что ServiceStack.OrmLite (ОРМ я использую) не поддерживает доступ к свойству Date, так же, как EF. Итак, теперь вопрос: как я могу решить эту ситуацию?

ответ

1

Итак, так я справился с ситуацией. Я хотел бы поблагодарить xanatos, чтобы указать мне на проблему DateTime.Date с ORM.

Я решил сравнить даты равенства путем временного интервала следующим образом:

public static Expression<Func<T, bool>> GetEqualExpression(string parameterName, 
    string comparisonValue) 
{ 
    var param = Expression.Parameter(typeof (T), parameterName); 
    var prop = Expression.Property(param, parameterName); 

    var propInfo = (PropertyInfo) Property.Member; 
    var propType = propInfo.PropertyType; 

    if (propType == typeof(DateTime)) 
    { 
     const string dateFormat = "ddd MMM d yyyy HH:mm:ss 'GMT'K"; 
     var parsedDate = DateTime.ParseExact(comparisonValue, dateFormat, CultureInfo.InvariantCulture); 

     var dayStart = new DateTime(parsedDate.Year, parsedDate.Month, parsedDate.Day, 0, 0, 0, 0); 
     var dayEnd = new DateTime(parsedDate.Year, parsedDate.Month, parsedDate.Day, 23, 59, 59, 999); 

     var left = Expression.Lambda<Func<T, bool>>(Expression.GreaterThanOrEqual(prop, Expression.Constant(dayStart)), param); 
     var right = Expression.Lambda<Func<T, bool>>(Expression.LessThanOrEqual(prop, Expression.Constant(dayEnd)), param); 

     return left.Compose(right, Expression.And); 
    } 

    ... 
} 

Это, кажется, сделать трюк.

0

Существует небольшая ошибка: вы должны использовать

Expression.Equal(property, constant) 

вместо

Expression.Equals(property, constant) 

И тогда, возможно, у вас есть проблемы в Поскольку я мог бы иметь более чем одно свойство для фильтрации, Сначала я захватил все BinaryExpression, которые мне нужно сравнить с любым объектным свойством и объединить их в одном выражении, которое передается запросу. Где пункт часть

Обратите внимание, что если вы используете Entity Framework, то DateTime.Date, вероятно, не поддерживается. См. https://stackoverflow.com/a/21186498/613130. Одним из возможных решений является использование EntityFunctions.TruncateTime.

+0

Да, извините, Expression.Equals - опечатка, я на самом деле использую Expression.Equal. Я не использую EntityFramework, а ServiceStack.OrmLite. Слияние выражений отлично работает с простыми типами в виде строки и чисел. Я подчеркнул концепцию, чтобы указать, что я не могу получить доступ к собственности напрямую. (например, в query.Where (q => q.StartDate.Date == parsedDate.Date) –

+0

@RobertoMauro Попробуйте проверить, можно ли выполнить запрос с 'Date' без использования выражения (так что построение действительно запроса типа' query. Где (q => q.StartDate.Date == someDate.Date) ', просто чтобы проверить, поддерживает ли Orm. – xanatos

+0

Да, вы правы, он не поддерживает доступ к свойству Date. Я принимаю это как должное. Я полагаю, что я ввернулся.: \ –

Смежные вопросы