我正在尽最大努力尝试创建一个模型映射器,该模型映射器通过 Linq2SQL 将任何表达式直接传递回 SQL,到目前为止,我已经设法将表达式树中的所有属性重新映射回原始模型。我遇到的问题是,每当我尝试将表达式树与 Linq2SQL 一起使用时,它都会失败并出现以下错误:
“参数 'modelParamName' 未绑定在指定的 LINQ to Entities 查询表达式中。”
我的代码如下(对于表达式重新映射器 - 我确实有很多扩展函数):
// Converting all members from using TModel to TElement
internal class ExpressionModifier<TModel, TElement> : ExpressionVisitor {
#region Members
#region Constructors
internal ExpressionModifier(IQueryable source) { this.source = source; }
#endregion
#region Variables
private IQueryable source;
#endregion
#region Methods
internal Expression Modify(Expression expression) { var result = this.Visit(expression); return result; }
protected override Expression VisitParameter(ParameterExpression node) {
if(node.Type == typeof(TModel)) { return Expression.Parameter(typeof(TElement), node.Name); }
return base.VisitParameter(node);
}
protected override Expression VisitConstant(ConstantExpression node) {
if(node.Value is IQueryable) { return Expression.Constant(this.source); }
return base.VisitConstant(node);
}
protected override Expression VisitMethodCall(MethodCallExpression node) {
var arguments = node.Arguments.Select(arg => this.Visit(arg));
var genericTypes = node.Method.GetGenericArguments().Select(arg=>this.VisitParameter(Expression.Parameter(arg)).Type);
var newMethod = typeof(Queryable).GetMethods().SingleOrDefault(method => method.MetadataToken == node.Method.MetadataToken);
return Expression.Call(newMethod.MakeGenericMethod(genericTypes.ToArray()), arguments);
}
protected override Expression VisitLambda<T>(Expression<T> node) {
var body = this.Visit(node.Body);
var parameters = node.Parameters.Select(parameter => this.VisitParameter(parameter) as ParameterExpression);
return Expression.Lambda(body, parameters.ToArray());
}
protected override Expression VisitMember(MemberExpression node) {
var memberName = node.Member.Name;
var modelAttribute = node.Member.GetAllAttributes().OfType<ModelAttribute>().SingleOrDefault();
if(modelAttribute != null && modelAttribute.Name.IsNotNull()) { memberName = modelAttribute.Name; }
var newMember = typeof(TElement).GetAllProperties().SingleOrDefault(property => property.Name == memberName);
if(newMember != null) { return Expression.MakeMemberAccess(Visit(node.Expression), newMember); }
return base.VisitMember(node);
}
#endregion
#endregion
}
任何帮助确定我可能做错了什么都将不胜感激。