как я могу хранить и повторно использовать части моих лямбда-выражений - PullRequest
11 голосов
/ 22 марта 2011

У меня есть блок кода, где кусок лямбда-выражения используется снова и снова.Как сохранить эту логику, чтобы я мог повторно использовать этот фрагмент выражения?

Например: давайте возьмем пример кода, приведенного ниже

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) - это часть, которую я хочу использовать повторно.

Есть ли способ, которым я могу повторно использовать толькоэти части выражения?

Ответы [ 3 ]

4 голосов
/ 22 марта 2011

Самый простой способ - это повторно использовать одно лямда-выражение, например:

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 .

3 голосов
/ 22 марта 2011

Вы не сказали нам, преобразовываются ли лямбда-выражения в деревья выражений или в делегаты, но, предполагая первое, я рекомендую использовать 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.

2 голосов
/ 22 марта 2011
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));
  }
  ...
  ...
}
...