Как я могу хранить и повторно использовать куски моих лямбда-выражений
У меня есть блок кода, где фрагмент выражения лямбда используется снова и снова. Как сохранить эту логику, чтобы я мог повторно использовать эту часть выражения?
Например: давайте возьмем пример приведенного ниже кода
Session.Query<DimensionGroup>()(dimgroup=>(dimgroup.Users.Where(map =>
((map.User.Key == _users.PublicUser.Key || map.User.Key == _users.CurrentUser.Key) &&
map.AccessLevel.ToAccessLevel() == AccessLevel.Write)).Count() > 0));
(map.User.Key == _users.PublicUser.Key || map.User.Key == _users.CurrentUser.Key)
является частью, которую я хочу повторно использовать.
и аналогичный фрагмент кода...
Session.Query<DimensionGroup>()(dimgroup =>(dimgroup.Users.Where(map => ((map.User.Key
==_users.PublicUser.Key || map.User.Key == _users.CurrentUser.Key) &&
map.AccessLevel.ToAccessLevel() == AccessLevel.Read)).Count() > 0));
(map.User.Key
== _users.PublicUser.Key || map.User.Key == _users.CurrentUser.Key)
является частью, которую я хочу повторно использовать.
Можно ли каким-то образом повторно использовать только те части выражения?
Ответы
Ответ 1
Самый простой способ - повторное использование одного выражения lamda, например:
Expression<Func<User, bool>> KeysMatch =
map => map.User.Key == _users.PublicUser.Key
|| map.User.Key == _users.CurrentUser.Key;
Session.Query<DimensionGroup>()(dimgroup=>(
dimgroup.Users.Where(KeysMatch)
.Where(map => map.AccessLevel.ToAccessLevel() == AccessLevel.Write))
.Count() > 0
));
Следующий шаг - фактически изменить сами деревья выражений, вызвав лямбда-выражения. Это сложнее, и если вы не хотите, чтобы с ним справиться и с ним справиться, проще с помощью инструментария. Я предлагаю LinqKit.
Ответ 2
Вы не сказали нам, что лямбда-выражения преобразуются в деревья выражений или для делегатов, но, предполагая первое, я рекомендую использовать PredicateBuilder.
Expression<Map, bool> predicate = map => map.User.Key == _users.PublicUser.Key
|| map.User.Key == _users.CurrentUser.Key;
Тогда ваш первый запрос будет выглядеть следующим образом:
var pred1 = predicate.And
(map => map.AccessLevel.ToAccessLevel() == AccessLevel.Write);
var query1 = Session.Query<DimensionGroup>
(dimgroup => dimgroup.Users.Where(pred1).Count() > 0);
И ваш второй:
var pred2 = predicate.And
(map => map.AccessLevel.ToAccessLevel() == AccessLevel.Read);
var query2 = Session.Query<DimensionGroup>
(dimgroup => dimgroup.Users.Where(pred2).Count() > 0);
Как вы можете видеть, есть возможности для факторизации еще большего числа обычаев; поскольку запросы, по-видимому, отличаются только разными AccessLevel
s.
Ответ 3
Func<Map, bool> func = (map => ((((map.User.Key ==_users.PublicUser.Key || map.User.Key == _users.CurrentUser.Key) && map.AccessLevel.ToAccessLevel() == AccessLevel.Read)).Count() > 0));
EDIT:
вы можете попробовать что-то вроде этого.
class MyClass{
Func<Map, bool> func = null;
MyClass()
{
func = (map => ((((map.User.Key ==_users.PublicUser.Key || map.User.Key == _users.CurrentUser.Key) && map.AccessLevel.ToAccessLevel() == AccessLevel.Read)).Count() > 0));
}
...
...
}