I've looked at the other questions around this and I just can't work out how to apply the answers to my particular situation. 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 a couple of different generic methods: one that gets the models using a provided Lambda that might look something like this:
GetWhere(p => p.PersonId == 1)
And one to get the models using a unique key - to make this flexible, I'd like to be able to specify the unique key using a Lambda:
GetByUniqueKey(p => p.PersonId, 1)
Or
GetByUniqueKey(b => b.BusinessId, 1)
Ideally GetByUniqueKey
would just be a shorthand method to build up an expression to send to GetWhere
, and then return the FirstOrDefault() result. But the logic to do this is completely escaping 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 take the uniqueKeyProperty
expression, invoke it on the supplied parameter somehow to get the property, and then use that property in the whereExpression
expression.
A note on duplicate questions: I know this looks like a duplicate of other similar questions, but please note I have read those and I just can't figure out how to apply those answers to my specific use case.
Some clarification in response to comments:
Put simply, I want to do the following:
I want to take the Expression p => p.PersonId
and the value 1, and generate a whereExpression
that looks like this p => p.PersonId == 1
. (Thanks @Rob)
You can build a new expression from the key selector and value provided like so:
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 querying by ID I wouldn't bother with this approach. Check out the other static methods on the Expression class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With