2015-01-20 2 views
-2

Я могу найти много информации о том, как изменить тело выражения, но я не могу найти ничего о том, как изменить ReturnType.Как преобразовать выражение <Func <T, object>> в выражение <Func <T, bool>>?

Вот код, который я написал, включающий вызов процедуры Convert, приведенной ниже.

private T[] CheckCreatedOnDate<T>(Expression<Func<T, object>> fieldExpression, T[] input, Data.Context context) where T : Entity 
    { 
     var fieldDelegate = fieldExpression.Compile(); 

     Expression<Func<T, bool>> predicateExpression = Convert(fieldExpression); 
     Func<T, bool> predicateDelegate = predicateExpression.Compile(); 
     Predicate<T> predicate = predicateDelegate.Invoke; 

     DbSet<T> dbSet = context.Set<T>(); 
     var data = dbSet.ToList(); 

     foreach (T inputRecord in input) 
     { 
      var fieldObject = fieldDelegate.Invoke(inputRecord); 

      var dataRecord = data.SingleOrDefault(x => Equals(predicate, fieldObject)); 

      if (dataRecord != null) 
      { 
       inputRecord.CreatedOn = dataRecord.CreatedOn; 
      } 
     } 

     return input; 
    } 

Этот метод должен вести себя очень похоже на метод AddOrUpdate в EF, однако это один просто заменить дату createdOn, если запись уже в Дб.

Мой код однако все еще не работает. Созданный предикат не кажется правильным, поскольку он никогда не находит соответствующую запись в Db.

Вся помощь очень ценится.

Приветствия Майк

+3

Что вы попробовали? Какова ваша конкретная проблема, где вы застряли? – nvoigt

+0

хорошо, я не думаю, что возвращаемый тип функции, которую вы меняете во время выполнения –

+0

Также вы можете добавить немного кода, например, само выражение – UrbanEsc

ответ

0

Если предположить, что fieldExpression что-то вроде (T e) => e.Field я пришел к выводу, что вы хотите найти в БД записи с одинаковым значением в столбце Field.

Попробуйте это:

foreach (T inputRecord in input) 
{ 
    object fieldObject = fieldDelegate.Invoke(inputRecord); 

    ParameterExpression p = fieldExpression.Parameters.First(); 
    // Equivalent to x => x.Field == fieldObject 
    Expression<Func<T, bool>> predicate = Expression.Lambda<Func<T, bool>>(
     // input.Field == fieldObject 
     Expression.Equal(
      // input.Field 
      fieldExpression.Body, 
      // constant from fieldObject 
      Expression.Constant(fieldObject) 
     ), 
     new []{ p } 
    ); 

    T dataRecord = dbSet.SingleOrDefault(predicate); 

    if (dataRecord != null) 
    { 
     inputRecord.CreatedOn = dataRecord.CreatedOn; 
    } 
} 

создать совершенно новый предикат в каждом цикле управляет принимать fieldExpression тело и передать его SingleOrDefault вызова.

+0

Я реализовал ваш метод Convert, но все-таки я не могу заставить свой код работать. Теперь я поставил код в вопросах. –

+0

Я изменил свой ответ – Krzysztof

+0

Фантастический! Благодарю. Просто одна мелочь, вам также нужно скомпилировать предикат, прежде чем передать его в SingleOrDefault. Я изменил ваш код и пометил его как ответ. –

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