Сначала я использую Entity Framework 4.1 Code.В моей сущности у меня есть три свойства даты / времени:
public class MyEntity
{
[Key]
public Id { get; set; }
public DateTime FromDate { get; set; }
public DateTime ToDate { get; set; }
[NotMapped]
public DateTime? QueryDate { get; set; }
// and some other fields, of course
}
В базе данных у меня всегда есть заполненные даты От / До.Я запрашиваю их, используя простое предложение where.Но в результирующем наборе я хочу включить дату, для которой я запрашивал.Мне нужно сохранить это для работы какой-то другой бизнес-логики.
Я работаю над методом расширения, чтобы сделать это, но у меня возникают проблемы:
public static IQueryable<T> WhereDateInRange<T>(this IQueryable<T> queryable, DateTime queryDate) where T : MyEntity
{
// this part works fine
var newQueryable = queryable.Where(e => e.FromDate <= queryDate &&
e.ToDate >= queryDate);
// in theory, this is what I want to do
newQueryable = newQueryable.Select(e =>
{
e.QueryDate = queryDate;
return e;
});
return newQueryable;
}
Это нене работаетЭто работает, если я использую IEnumerable, но я хочу сохранить его как IQueryable, чтобы все выполнялось на стороне базы данных, и этот метод расширения все еще можно использовать в любой части другого запроса.Когда это IQueryable, я получаю ошибку компиляции следующего:
Лямбда-выражение с телом оператора не может быть преобразовано в дерево выражений
Если это был SQL,Я бы просто сделал что-то вроде этого:
SELECT *, @QueryDate as QueryDate
FROM MyEntities
WHERE @QueryDate BETWEEN FromDate AND ToDate
Итак, вопрос в том, как я могу преобразовать дерево выражений, которое мне уже нужно, чтобы включить это дополнительное присвоение свойства?Я изучил IQueryable.Expression и IQueryable.Provider.CreateQuery - где-то есть решение.Может быть, выражение присваивания можно добавить к существующему дереву выражений?Я недостаточно знаком с методами дерева выражений, чтобы понять это.Любые идеи?
Пример использования
Чтобы уточнить, цель состоит в том, чтобы иметь возможность выполнить что-то вроде этого:
var entity = dataContext.Set<MyEntity>()
.WhereDateInRange(DateTime.Now)
.FirstOrDefault();
И иметьDateTime.Now сохраняется в QueryDate результирующей строки, БЕЗ возврата из запроса к базе данных более одной строки.(С помощью решения IEnumerable несколько строк возвращаются до того, как FirstOrDefault выберет нужную нам строку.)
Другая идея
Я могу пойти дальше и отобразить QueryDate как реальное полеи установите для DatabaseGeneratedOption значение Computed.Но тогда мне понадобится какой-нибудь способ вставить «@QueryDate as QueryDate» в SQL, созданный операторами выбора EF.Поскольку он вычисляется, EF не будет пытаться предоставлять значения во время обновления или вставки.Так как же я могу добавить собственный SQL в операторы select?