How can I map
from: Expression<Func<TEntity, bool>>
to: Expression<Func<TDbEntity, bool>>
where TEntity: class, new() and TDbEntity: class, new()
TEntity is from Domain and TDbEntity is from Infrastructure layer, but have same properties.
It is possible?
For relatively simple cases (and I guess in your case expressions are simple) you can use ExpressionVisitor
with only a couple of overrides. For example:
public static class ExpressionExtensions {
public static Expression<Func<TTo, bool>> ReplaceParameter<TFrom, TTo>(this Expression<Func<TFrom, bool>> target) {
return (Expression<Func<TTo, bool>>) new WhereReplacerVisitor<TFrom, TTo>().Visit(target);
}
private class WhereReplacerVisitor<TFrom, TTo> : ExpressionVisitor {
private readonly ParameterExpression _parameter = Expression.Parameter(typeof(TTo), "c");
protected override Expression VisitLambda<T>(Expression<T> node) {
// replace parameter here
return Expression.Lambda(Visit(node.Body), _parameter);
}
protected override Expression VisitMember(MemberExpression node) {
// replace parameter member access with new type
if (node.Member.DeclaringType == typeof(TFrom) && node.Expression is ParameterExpression) {
return Expression.PropertyOrField(_parameter, node.Member.Name);
}
return base.VisitMember(node);
}
}
}
Usage is:
Expression<Func<ErrorModel, bool>> where = (c) => c.Created <= DateTime.UtcNow && c.ErrorCode == "code";
var replaced = where.ReplaceParameter<ErrorModel, Error>();
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