动态表达式树谓词,带有要枚举的枚举

时间:2019-07-17 13:29:58

标签: c# expression-trees

我有充当DTO的实体类和代表表的域类,它们来自Entity Framework模型。我想创建一个从function Child(props) { return <div {...props}>Hello</div>; } export default function Parent(props) { return <Child {...props} />; } 中使用的通用过滤器方法,但是我不想将实体框架模型类公开给控制器,我希望控制器仅处理DTO。 所以,我有这个通用方法:

Controller

但是,IEnumerable<Employee> Filter(Expression<Func<Employee, bool>> filter); 类的Employee在表中具有DTO类型的Status枚举,它是System.Int32类型的Status_id列。 当我像这样使用此功能时:

int

我收到以下异常:

  

System.InvalidOperationException:不允许将子表达式从类型'Entities.Statuses'重写为类型'System.Int64',因为这会改变操作的含义。如果这是故意的,请覆盖“ VisitUnary”并将其更改为允许此重写。”

这是我正在使用的代码,请注意memberMapper是一个简单的return employeeRepository.Filter( item => item.Age > 40 && item.StatusId != Statuses.Deleted); ,它将Func<string,string>类属性的名称转换为与数据库表匹配的DTO类属性名称列名。

EntityFramework

正在使用public static class PredicateMapper { public static Expression<Func<TTo, bool>> CastParameter<TFrom, TTo>( this Expression<Func<TFrom, bool>> predicate, Func<string,string> memberMapper) { return new ParameterTypeVisitor<TFrom, TTo>(predicate, memberMapper).Transform(); } } class ParameterTypeVisitor<TSource, TDestination> : ExpressionVisitor { private readonly Expression<Func<TSource, bool>> _expression; private readonly Func<string, string> _propertyMapper; private readonly Dictionary<string, ParameterExpression> _parameters; public ParameterTypeVisitor(Expression<Func<TSource, bool>> expression, Func<string,string> propertyMapper) { _parameters = expression.Parameters .ToDictionary(p => p.Name, p => Expression.Parameter(typeof(TDestination), p.Name)); _expression = expression; _propertyMapper = propertyMapper; } public Expression<Func<TDestination, bool>> Transform() { return (Expression<Func<TDestination, bool>>) Visit(_expression); } protected override Expression VisitMember(MemberExpression node) { var sourceType = typeof(TSource); if (node.Member.DeclaringType == sourceType || IsExistOnBaseClass(sourceType.BaseType,node.Member.DeclaringType)) { var memberName = node.Member.Name; var destinationProperty = typeof(TDestination).GetProperty(_propertyMapper(memberName)); if (destinationProperty != null) { // Return Property from TDestination var expression = Visit(node.Expression); return Expression.MakeMemberAccess(expression, destinationProperty); } } return base.VisitMember(node); } private bool IsExistOnBaseClass(Type type, Type typeToCheck) { if (type == null) return false; if (type == typeToCheck) return true; return IsExistOnBaseClass(type.BaseType, typeToCheck); } protected override Expression VisitParameter(ParameterExpression node) { var parameter = _parameters[node.Name]; return parameter; } protected override Expression VisitLambda<T>(Expression<T> node) { try { var expression = Visit(node.Body); return Expression.Lambda(expression, _parameters.Select(x => x.Value)); } catch (Exception e) { throw; } } } 方法抛出异常。

0 个答案:

没有答案