Reputation: 24053
I am trying to create an expression for using in entity framework query. I created two expressions:
public Expression<Func<IEntityPriceDefinition, bool>> IsMatchExpression(long additionId)
{
return x => x.PriceDefinition.AdditionsPrices.Any(a => a.AdditionId == additionId);
}
public Expression<Func<IEntityPriceDefinition, bool>> IsMatchExpression(
long? inviterId, long? routeId, long? luggageTypeId)
{
return x =>
(inviterId.HasValue || routeId.HasValue || luggageTypeId.HasValue) &&
!(
(x.PriceDefinition.InviterId.HasValue && inviterId.HasValue &&
PriceDefinition.InviterId.Value != inviterId.Value) ||
(PriceDefinition.LuggageTypeId.HasValue && luggageTypeId.HasValue &&
PriceDefinition.LuggageTypeId.Value != luggageTypeId.Value) ||
(PriceDefinition.InviterId.HasValue && inviterId.HasValue &&
PriceDefinition.InviterId.Value != inviterId.Value)
);
}
And now I am willing to combine them:
public Expression<Func<IEntityPriceDefinition, bool>> IsMatchExpression(
long? inviterId, long? routeId, long? luggageTypeId, long additionId)
{
return IsMatchExpression(inviterId, routeId, luggageTypeId) &&
IsMatchExpression(additionId);
}
This method doesn't compiles. I also have the feeling I did something wrong. How can I fix it?
EDIT:
I forgotenn importent part! the question updated.
Upvotes: 1
Views: 690
Reputation: 38980
You'll have to work with the expression components directly to do this.
public Expression<Func<IEntityPriceDefinition, bool>> IsMatchExpression(
long? inviterId, long? routeId, long? luggageTypeId, long additionId)
{
var a = IsMatchExpression(inviterId, routeId, luggageTypeId);
var b = IsMatchExpression(additionId);
var p = Expression.Parameter(typeof(IEntityPriceDefinition),"x");
var c = Expression.AndAlso(Expression.Invoke(a,p),Expression.Invoke(b,p));
var r = Expression.Lambda<Func<IEntityPriceDefinition, bool>>(c,p);
return r;
}
This could be made more sophisticated by breaking out the .Body
from each of the two expressions and replacing (using an ExpressionVisitor
) the parameters with the new parameter; and each of your two working methods could be changed to bind their parameters into ConstantExpression
s, losing the lambda expression syntax altogether. Those changes may in fact be necessary to make an expression that can work properly with entity framework, but this will take some time for me to work out to post in the answer.
See also How can I compose an Entity Framework query from smaller, resusable queries?
Upvotes: 1
Reputation: 24053
Just created combined method:
public Expression<Func<IEntityPriceDefinition, bool>> IsMatchExpression(
long? inviterId, long? routeId, long? luggageTypeId, long additionId)
{
return x =>
(inviterId.HasValue || routeId.HasValue || luggageTypeId.HasValue) &&
(x.PriceDefinition.AdditionsPrices.Any(a => a.AdditionId == additionId)) &&
!(
(x.PriceDefinition.InviterId.HasValue && inviterId.HasValue &&
PriceDefinition.InviterId.Value != inviterId.Value) ||
(PriceDefinition.LuggageTypeId.HasValue && luggageTypeId.HasValue &&
PriceDefinition.LuggageTypeId.Value != luggageTypeId.Value) ||
(PriceDefinition.InviterId.HasValue && inviterId.HasValue &&
PriceDefinition.InviterId.Value != inviterId.Value)
);
}
Not the best solution but it works.
Upvotes: 0
Reputation: 5144
ok could it be sth like
var x = IsMatchExpression(inviterId, routeId, luggageTypeId)
var y = IsMatchExpression(additionId);
return arg => x(arg) && y(arg)
?
Upvotes: 0