how can i store and reuse pieces of my lambda expressions
Asked Answered
D

3

12

I have a block of code where a piece of the lambda expression is used again and again. How can store this logic so that i can reuse this expression piece?

Eg: lets take the example of the code given below

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) being the portion I want to reuse.

and a similar piece of code...

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) being the portion I want to reuse.

Is there some way I can reuse just those parts of the expression?

Duchamp answered 22/3, 2011 at 19:55 Comment(0)
M
5

The easiest way is to reuse a single lamda expression, like so:

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

The next step up is to actually modify expression trees themselves by invoking lambda expressions. This is more complicated, and unless you want to get down and dirty with it is easier with a toolkit. I suggest LinqKit.

Mcbee answered 22/3, 2011 at 20:4 Comment(0)
I
3

You haven't told us if the lambda expressions are being converted to expression-trees or to delegates, but assuming the former, I recommend using PredicateBuilder.

Expression<Map, bool> predicate = map =>  map.User.Key == _users.PublicUser.Key 
                                       || map.User.Key == _users.CurrentUser.Key;

Then your first query becomes:

var pred1 = predicate.And
            (map => map.AccessLevel.ToAccessLevel() == AccessLevel.Write);

var query1 = Session.Query<DimensionGroup>
    (dimgroup => dimgroup.Users.Where(pred1).Count() > 0);

And your second:

var pred2 = predicate.And
            (map => map.AccessLevel.ToAccessLevel() == AccessLevel.Read);

var query2 = Session.Query<DimensionGroup>
    (dimgroup => dimgroup.Users.Where(pred2).Count() > 0);

As you can see, there is scope for factoring out even more commonalities; since the queries appear to only differ by different AccessLevels.

Isherwood answered 22/3, 2011 at 20:6 Comment(0)
T
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));

EDIT:

you could try something like this.

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));
  }
  ...
  ...
}
Tephrite answered 22/3, 2011 at 19:57 Comment(4)
Depending on the usage scenario, it may be wiser to assign to an Expression instead of a delegate.Matlock
that was quick....but iv tried this in vain... _users is a non static field which is not allowed in field initializerDuchamp
also im assuming u meant Func<Map,bool> cause bool is my return typeDuchamp
Maybe you can initialize it in the constructor? and yes bool is the return type.Tephrite

© 2022 - 2024 — McMap. All rights reserved.