我如何存储和重用我的lambda表达式

时间:2011-03-22 19:55:31

标签: c# lambda expression

我有一段代码,其中一段又一次使用lambda表达式。如何存储这个逻辑,以便我可以重用这个表达式?

例如:让我们以下面给出的代码为例

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 个答案:

答案 0 :(得分:4)

最简单的方法是重用单个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
));

下一步是通过调用lambda表达式来实际修改表达式树。这更复杂,除非你想要使用工具包更容易理解它。我建议LinqKit

答案 1 :(得分:3)

你没有告诉我们lambda表达式是转换为表达式树还是代表,但假设前者,我建议使用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 :(得分:2)

Func<Map, bool> func = (map => ((((map.User.Key ==_users.PublicUser.Key || map.User.Key == _users.CurrentUser.Key) && map.AccessLevel.ToAccessLevel() == AccessLevel.Read)).Count() > 0));

编辑:

你可以尝试这样的事情。

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));
  }
  ...
  ...
}