2016-01-07 2 views
0

У меня есть таблица SQL, в которой отмеченные записи периодически «замечены» и удаляются. Мне нужно реплицировать этот набор данных, один раз для производительности и дважды, чтобы временно сохранить удаленные записи.EF безопасная комбинация лямбда - (x, y) => x> y в (x) => x> константа

Я начал с написания обертки около DbSet<T>, чтобы сделать некоторое условное кэширование набора данных.

Кэш инициализируется при запуске, а затем периодически обновляется.

У меня есть инициализации предикат, например:

Func<Type_x, bool> predicate = entity => true 

, который используется для инициализации:

cache(dbset.Where(predicate)); 

Позже я обновлю на основе второго предиката, который состоит из двух частей:

// a function to get value of Type_y from dbset (dbset is DbSet<Type_x>) 
Type_y preUpdate = dbset => dbset.Select(row => row.LastModified).Max() 

// the problem predicate 
Func<Type_x, Type_y, bool> = (dbset, preUpdate) => dbset.LastModified > preUpdate; 

Как получить от последнего Func<Type_x, Type_y, bool> к безопасному предикату EF e Func<Type_x, bool>?

Для ясности, второй параметр preUpdate типа Type_y будет вычислена, а затем должно быть объединены в «проблема предиката», так что он становится 1. предикат типа Func<Type_x, bool> и 2. Результаты в предложении в генерируемый SQL что-то вроде WHERE [TABLE].[LAST_MODIFIED] > SOME_VALUE

Я думаю, что могу использовать ExpressionVisitor, но я не уверен, как действовать дальше.

ответ

0

Вдохновленный ответ LegionMammal978, в что мне нужно было что-то вроде этого:

Func<ConcurrentDictionary<Guid, T>, Expression<Func<T, bool>>> updatePredicateBuilder

который я использовал:

CachedSet<DbView>.Get(this, DbViewDbSet, 
    (DbView entity) => true, 
    (DbSet<DbView> set) => 
    { 
     var k = set.Select(e => e.Value.LastModified).Max(); 
     return g => g.LastModified >= k; 
    }); 

примечания: без блока set => { /* here */ }, EF будет тянуть обратно все записи в исполняющем перед выполнением пункта.

Для ясности, в рамках метода обновления:

var pred = this.updatePredicateBuilder(this.cachedDbSet); 
var result = baseDbSet.Where(pred).ToList() /* materialize */; 
1

Опцион ...

Func<Type_y, Func<Type_x, bool>> pred = preUpdate => dbset => dbset.LastModified > preUpdate; 

(. Я не проверял, возможно, придется добавить еще круглые скобки) Затем, чтобы использовать его:

Func<Type_x, bool> created = pred(myPreUpdate); 
+0

Благодарим Вас за это. Я чувствую себя глупо, что не думал об этом. Ваш ответ почти на месте! –

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