Using logic from one lambda within the second lambda

I looked at other questions related to this, and I just can't figure out how to apply the answers in my specific situation. Let's say you have a couple of models that look like this:

public class Person { public int PersonId { get; set; } } public class Business { public int BusinessId { get; set; } } 

I want to be able to write several different general methods: one that gets the models using the provided Lambda, which might look something like this:

 GetWhere(p => p.PersonId == 1) 

And one, to get models using a unique key - to make it flexible, I would like to be able to specify a unique key using Lambda:

 GetByUniqueKey(p => p.PersonId, 1) 

or

 GetByUniqueKey(b => b.BusinessId, 1) 

Ideally, GetByUniqueKey would be just a shorthand method for creating an expression to send to GetWhere and then returning the result of FirstOrDefault (). But the logic for this completely eludes me. What I want to do:

 public IEnumerable<TModel> GetWhere(Expression<Func<TModel, bool>> whereExpression) { // Get from DB using expression provided } public TModel GetByUniqueKey<TUniqueKey>( Expression<Func<TModel, TUniqueKey>> uniqueKeyProperty, TUniqueKey value) { return GetWhere(m => uniqueKeyProperty(m) == value).FirstOrDefault(); } 

So, I want to accept the uniqueKeyProperty expression, call it on the provided parameter somehow to get the property, and then use this property in the whereExpression expression.

Note on duplicate questions: I know this is like a duplicate of other similar questions, but please note that I read them and I just can’t figure out how to apply these answers in my particular use case.

Some clarifications in response to the comments :

Simply put, I want to do the following:

I want to take the expression p => p.PersonId and the value 1 and generate a whereExpression , which looks like p => p.PersonId == 1 . (Thanks @Rob)

+5
source share
2 answers

You can create a new expression from the key selector and the value specified as follows:

 public TModel GetByUniqueKey<TUniqueKey>( Expression<Func<TModel, TUniqueKey>> uniqueKeySelector, TUniqueKey value) { return GetWhere(Expression.Lambda<Func<TModel,bool>>( Expression.MakeBinary( ExpressionType.Equal, uniqueKeySelector.Body, Expression.Constant(value, typeof(TUniqueKey))), uniqueKeySelector.Parameters)); } 

For a request by ID, I would not worry about that. Check out the other static methods in the expression class .

+1
source

Apparently you would like to implement some kind of polymorphism, one of the possibilities would be to have Person and Business inherit from the same base class or inherit from the same interface and share the Id property. You can define

 public class Identifiable { public int Id { get; set; } } 

and make Person and Business inherit from. Then callback

 Func<Identifiable,bool> = iIdentifiable => iIdentifiable.Id == 1 

can be called for objects of both classes. However, the source classes must be modified in order for this approach to work.

0
source

All Articles