可怕的"参数没有被绑定在指定的LINQ to Entities查询EX pression"例外 [英] The dreaded "parameter was not bound in the specified LINQ to Entities query expression" exception

查看:1088
本文介绍了可怕的"参数没有被绑定在指定的LINQ to Entities查询EX pression"例外的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想获得的当然pressions的理解。我打了可怕的参数没有被指定LINQ到实体约束查询EX pression异常。我见过飞碟双向之前回答这个问题,以及其他在线。不过,我只是不能看的问题。我使用的科林·米克的例子<一href="http://blogs.msdn.com/b/meek/archive/2008/05/02/linq-to-entities-combining-$p$pdicates.aspx">http://blogs.msdn.com/b/meek/archive/2008/05/02/linq-to-entities-combining-$p$pdicates.aspx和Matt沃伦的VisitorEx pression类<一href="http://blogs.msdn.com/b/mattwar/archive/2007/07/31/linq-building-an-iqueryable-provider-part-ii.aspx">http://blogs.msdn.com/b/mattwar/archive/2007/07/31/linq-building-an-iqueryable-provider-part-ii.aspx.我使用一个控制台应用程序在VS 2010中,框架4.0。很抱歉,如果这是白费口舌,因为它已经被问了。感谢您的帮助。

要彻底,所有的code是如下:

 类节目
{
    静态无效的主要(字串[] args)
    {
        防爆pression&LT; Func键&LT;汽车,布尔&GT;&GT; theCarIsRed = C =&GT; c.Color ==红;
        防爆pression&LT; Func键&LT;汽车,布尔&GT;&GT; theCarIsCheap = C =&GT; c.Price&LT; 10.0;
        防爆pression&LT; Func键&LT;汽车,布尔&GT;&GT; theCarIsRedOrCheap = theCarIsRed.Or(theCarIsCheap);

        车一=新车(){CarId = 1,颜色=红,价格= 10.0};
        车二=新车(){CarId = 2,颜色=蓝,价格= 9.0};
        三厢=新车(){CarId = 3,颜色=黑色,价格= 5.0};
        汽车4 =新车(){CarId = 4,颜色=红,价格= 5.0};

        EntityDBContext上下文=新EntityDBContext();
        context.CarEntity.Add(之一);
        context.CarEntity.Add(二);
        context.CarEntity.Add(三级);
        context.CarEntity.Add(4件);

        使用(VAR DB =上下文)
        {
            // 砰
            变种查询= db.CarEntity.AsQueryable()如(theCarIsRedOrCheap).ToList()。

            的foreach(查询VAR项)
            {
                Console.WriteLine(item.Color,item.Price);
            }
        }

        Console.ReadKey();
    }
}

公共类车
{
    [键]
    公众诠释CarId {获得;组; }
    公共串色{获得;组; }
    公共双价{获得;组; }
}


公共静态类工具
{
    公共静态防爆pression&LT; T&GT;撰写&LT; T&GT;(此例pression&LT; T&gt;首先,
        防爆pression&LT; T&GT;第二,Func键和LT;防爆pression,防爆pression,防爆pression&GT;合并)
    {
        VAR地图= first.Parameters.Select((F,I)=&gt;新建{F,S = second.Parameters [I]})ToDictionary(P =&GT; PS,P =&GT; PF)。

        VAR secondBody = ParameterRebinder.ReplaceParameters(地图,second.Body);

        返回前pression.Lambda&LT; T&GT;(合并(first.Body,second.Body),first.Parameters);
    }

    公共静态防爆pression&LT; Func键&LT; T,布尔&GT;&GT;和&lt; T&GT;(此例pression&LT; Func键&LT; T,布尔&GT;&gt;首先,防爆pression&LT; Func键&LT; T,布尔&GT;&gt;第二个)
    {
        返回first.Compose(第二,防爆pression.And);
    }

    公共静态防爆pression&LT; Func键&LT; T,布尔&GT;&GT;或LT; T&GT;(此例pression&LT; Func键&LT; T,布尔&GT;&gt;首先,防爆pression&LT; Func键&LT; T,布尔&GT;&gt;第二个)
    {
        返回first.Compose(第二,防爆pression.Or);
    }
}


公共类ParameterRebinder:防爆pressionVisitor
{
    私人只读字典&LT; ParameterEx pression,ParameterEx pression&GT;地图;

    公共ParameterRebinder(词典&LT; ParameterEx pression,ParameterEx pression&GT;地图)
    {
        this.map =地图?新的字典&LT; ParameterEx pression,ParameterEx pression&GT;();
    }

    公共静态防爆pression ReplaceParameters(词典&LT; ParameterEx pression,ParameterEx pression&GT;地图,防爆pression EXP)
    {
        返回新ParameterRebinder(图).Visit(EXP);
    }

    保护覆盖防爆pression VisitParameter(ParameterEx pression parmEx)
    {
        ParameterEx pression更换;
        如果(map.TryGetValue(parmEx,置换,))
        {
            parmEx =更换;
        }

        返回base.VisitParameter(parmEx);
    }
}

公共抽象类防爆pressionVisitor
{
    保护防爆pressionVisitor()
    {
    }

    受保护的虚拟防爆pression访问(出pression EXP)
    {
        如果(EXP == NULL)
        {
            返回EXP;
        }

        开关(exp.NodeType)
        {
            案前pressionType.Negate:
            案前pressionType.NegateChecked:
            案前pressionType.Not:
            案前pressionType.Convert:
            案前pressionType.ConvertChecked:
            案前pressionType.ArrayLength:
            案前pressionType.Quote:
            案前pressionType.TypeAs:
                返回this.VisitUnary((UnaryEx pression)EXP);
            案前pressionType.Add:
            案前pressionType.AddChecked:
            案前pressionType.Subtract:
            案前pressionType.SubtractChecked:
            案前pressionType.Multiply:
            案前pressionType.MultiplyChecked:
            案前pressionType.Divide:
            案前pressionType.Modulo:
            案前pressionType.And:
            案前pressionType.AndAlso:
            案前pressionType.Or:
            案前pressionType.OrElse:
            案前pressionType.LessThan:
            案前pressionType.LessThanOrEqual:
            案前pressionType.GreaterThan:
            案前pressionType.GreaterThanOrEqual:
            案前pressionType.Equal:
            案前pressionType.NotEqual:
            案前pressionType.Coalesce:
            案前pressionType.ArrayIndex:
            案前pressionType.RightShift:
            案前pressionType.LeftShift:
            案前pressionType.ExclusiveOr:
                返回this.VisitBinary((BinaryEx pression)EXP);
            案前pressionType.TypeIs:
                返回this.VisitTypeIs((TypeBinaryEx pression)EXP);
            案前pressionType.Conditional:
                返回this.VisitConditional((ConditionalEx pression)EXP);
            案前pressionType.Constant:
                返回this.VisitConstant((ConstantEx pression)EXP);
            案前pressionType.Parameter:
                返回this.VisitParameter((ParameterEx pression)EXP);
            案前pressionType.MemberAccess:
                返回this.VisitMemberAccess((MemberEx pression)EXP);
            案前pressionType.Call:
                返回this.VisitMethodCall((MethodCallEx pression)EXP);
            案前pressionType.Lambda:
                返回this.VisitLambda((LambdaEx pression)EXP);
            案前pressionType.New:
                返回this.VisitNew((NewEx pression)EXP);
            案前pressionType.NewArrayInit:
            案前pressionType.NewArrayBounds:
                返回this.VisitNewArray((NewArrayEx pression)EXP);
            案前pressionType.Invoke:
                返回this.VisitInvocation((InvocationEx pression)EXP);
            案前pressionType.MemberInit:
                返回this.VisitMemberInit((MemberInitEx pression)EXP);
            案前pressionType.ListInit:
                返回this.VisitListInit((ListInitEx pression)EXP);
            默认:
                抛出新的异常(的String.Format(未处理前pression类型:{0}',exp.NodeType));

        }
    }

    受保护的虚拟MemberBinding VisitBinding(MemberBinding绑定)
    {
        开关(binding.BindingType)
        {
            案例MemberBindingType.Assignment:
                返回this.VisitMemberAssignment((MemberAssignment)绑定);
                案例MemberBindingType.MemberBinding:
                返回this.VisitMemberMemberBinding((MemberMemberBinding)绑定);
                案例MemberBindingType.ListBinding:
                返回this.VisitMemberListBinding((MemberListBinding)绑定);
            默认:
                抛出新的异常(的String.Format(未处理的绑定类型{0}',binding.BindingType));
        }
    }

    受保护的虚拟防爆pression VisitListInit(ListInitEx pression INIT)
    {
        NewEx pression N = this.VisitNew(init.NewEx pression);
        IEnumerable的&LT; ElementInit&GT;初始化= this.VisitElementInitializerList(init.Initializers);

        如果(N!= init.NewEx pression ||初始化!= init.Initializers)
        {
            返回前pression.ListInit(N,初始化);
        }

        返回初始化;
    }

    受保护的虚拟防爆pression VisitMemberInit(MemberInitEx pression memberInitEx pression)
    {
        NewEx pression N = this.VisitNew(memberInitEx pression.NewEx pression);
        IEnumerable的&LT; MemberBinding&GT;绑定= this.VisitBindingList(memberInitEx pression.Bindings);

        如果(N!= memberInitEx pression.NewEx pression ||绑定!= memberInitEx pression.Bindings)
        {
            返回前pression.MemberInit(N,绑定);
        }

        返回memberInitEx pression;
    }

    受保护的虚拟防爆pression VisitInvocation(InvocationEx pression invocationEx pression)
    {
        IEnumerable的&LT;防爆pression&GT;的args = this.VisitEx pressionList(invocationEx pression.Arguments);
        防爆pression EXPR = this.Visit(invocationEx pression.Ex pression);

        如果(参数!= invocationEx pression.Arguments || expr的!= invocationEx pression.Ex pression)
        {
            返回前pression.Invoke(表达式,参数);
        }

        返回invocationEx pression;
    }

    受保护的虚拟防爆pression VisitNewArray(NewArrayEx pression newArrayEx pression)
    {
        IEnumerable的&LT;防爆pression&GT; exprs = this.VisitEx pressionList(newArrayEx pression.Ex pressions);

        如果(exprs!= newArrayEx pression.Ex pressions)
        {
            如果(newArrayEx pression.NodeType ==前pressionType.NewArrayInit)
            {
                返回前pression.NewArrayInit(newArrayEx pression.Type.GetElementType(),exprs);
            }
            其他
            {
                返回前pression.NewArrayBounds(newArrayEx pression.Type.GetElementType());
            }
        }

        返回newArrayEx pression;
    }

    受保护的虚拟NewEx pression VisitNew(NewEx pression newEx pression)
    {
        IEnumerable的&LT;防爆pression&GT;的args = this.VisitEx pressionList(newEx pression.Arguments);

        如果(参数!= newEx pression.Arguments)
        {
            如果(newEx pression.Members!= NULL)
            {
                返回前pression.New(newEx pression.Constructor,ARGS,newEx pression.Members);
            }
            其他
            {
                返回前pression.New(newEx pression.Constructor,参数);
            }
        }

        返回newEx pression;
    }

    受保护的虚拟防爆pression VisitLambda(LambdaEx pression lambdaEx pression)
    {
        防爆pression体= this.Visit(lambdaEx pression.Body);
        如果(身体!= lambdaEx pression.Body)
        {
            返回前pression.Lambda(lambdaEx pression.Type,身体,lambdaEx pression.Parameters);
        }

        返回lambdaEx pression;
    }

    受保护的虚拟防爆pression VisitMethodCall(MethodCallEx pression methodCallEx pression)
    {
        防爆pression的obj = this.Visit(methodCallEx pression.Object);
        IEnumerable的&LT;防爆pression&GT;的args = this.VisitEx pressionList(methodCallEx pression.Arguments);

        如果(OBJ!= methodCallEx pression.Object ||的args!= methodCallEx pression.Arguments)
        {
            返回前pression.Call(OBJ,methodCallEx pression.Method,参数);
        }

        返回methodCallEx pression;
    }

    受保护的虚拟防爆pression VisitMemberAccess(MemberEx pression memberEx pression)
    {
        防爆pression EXP = this.Visit(memberEx pression.Ex pression);

        如果(EXP!= memberEx pression.Ex pression)
        {
            返回前pression.MakeMemberAccess(EXP,memberEx pression.Member);
        }

        返回memberEx pression;
    }

    受保护的虚拟防爆pression VisitParameter(ParameterEx pression parameterEx pression)
    {
        返回parameterEx pression;
    }

    受保护的虚拟防爆pression VisitConstant(ConstantEx pression constantEx pression)
    {
        返回constantEx pression;
    }

    受保护的虚拟防爆pression VisitConditional(ConditionalEx pression conditionalEx pression)
    {
        防爆pression测试= this.Visit(conditionalEx pression.Test);
        防爆pression ifTrue = this.Visit(conditionalEx pression.IfTrue);
        防爆pression ifFalse = this.Visit(conditionalEx pression.IfFalse);

        如果(测试!= conditionalEx pression.Test || ifTrue!= conditionalEx pression.IfTrue || ifFalse!= conditionalEx pression.IfFalse)
        {
            返回前pression.Condition(测试,ifTrue,ifFalse);
        }

        返回conditionalEx pression;
    }

    受保护的虚拟防爆pression VisitTypeIs(TypeBinaryEx pression typeBinaryEx pression)
    {
        防爆pression EXPR = this.Visit(typeBinaryEx pression.Ex pression);
        如果(表达式!= typeBinaryEx pression)
        {
            返回前pression.TypeIs(表达式,typeBinaryEx pression.TypeOperand);
        }

        返回typeBinaryEx pression;
    }

    受保护的虚拟防爆pression VisitBinary(BinaryEx pression binaryEx pression)
    {
        防爆pression左= this.Visit(binaryEx pression.Left);
        防爆pression右= this.Visit(binaryEx pression.Right);
        防爆pression转换= this.Visit(binaryEx pression.Conversion);

        如果(左!= binaryEx pression.Left ||没错!= binaryEx pression.Right ||转换!= binaryEx pression.Conversion)
        {
            如果(binaryEx pression.NodeType ==前pressionType.Coalesce和放大器;&安培;!binaryEx pression.Conversion = NULL)
            {
                返回前pression.Coalesce(左,右,转换为LambdaEx pression);
            }
            其他
            {
                返回前pression.MakeBinary(binaryEx pression.NodeType,左,右,binaryEx pression.IsLiftedToNull,
                                             binaryEx pression.Method);
            }
        }

        返回binaryEx pression;
    }

    受保护的虚拟防爆pression VisitUnary(UnaryEx pression unaryEx pression)
    {
        防爆pression操作数= this.Visit(unaryEx pression.Operand);
        如果(操作数!= unaryEx pression.Operand)
        {
            返回前pression.MakeUnary(unaryEx pression.NodeType,操作数,unaryEx pression.Type,
                                        unaryEx pression.Method);
        }

        返回unaryEx pression;
    }

    受保护的虚拟ReadOnlyCollection还&LT;防爆pression&GT; VisitEx pressionList(ReadOnlyCollection还&LT;防爆pression&GT;原)
    {
        名单&LT;防爆pression&GT;名单= NULL;

        的for(int i = 0,N = original.Count;我n种;我++)
        {
            防爆pression P = this.Visit([i]原);
            如果(名单!= NULL)
            {
                list.Add(对);
            }
            否则,如果(P!= [i]原)
            {
                名单=新的名单,其中,前pression&GT;(N);
                对于(INT J = 0; J&LT;我; J ++)
                {
                    list.Add(原[J]);
                }

                list.Add(对);
            }
        }

        返回列表!= NULL? list.AsReadOnly():原件;
    }

    受保护的虚拟的IEnumerable&LT; MemberBinding&GT; VisitBindingList(ReadOnlyCollection还&LT; MemberBinding&GT;原)
    {
        名单&LT; MemberBinding&GT;名单= NULL;

        的for(int i = 0,N = original.Count;我n种;我++)
        {
            MemberBinding B = this.VisitBinding([i]原);

            如果(名单!= NULL)
            {
                list.Add(B);
            }
            否则,如果(B!= [i]原)
            {
                名单=新的名单,其中,MemberBinding&GT;(N);

                对于(INT J = 0; J&LT;我; J ++)
                {
                    list.Add(原[J]);
                }

                list.Add(B);
            }
        }

        如果(名单!= NULL)
        {
            返回列表;
        }

        回到原来的;
    }

    受保护的虚拟MemberAssignment VisitMemberAssignment(MemberAssignment分配)
    {
        防爆pression E = this.Visit(assignment.Ex pression);

        如果(E!= assignment.Ex pression)
        {
            返回前pression.Bind(assignment.Member,E);
        }

        返回分配;
    }

    受保护的虚拟MemberMemberBinding VisitMemberMemberBinding(MemberMemberBinding绑定)
    {
        IEnumerable的&LT; MemberBinding&GT;绑定= this.VisitBindingList(binding.Bindings);

        如果(绑定!= binding.Bindings)
        {
            返回前pression.MemberBind(binding.Member,绑定);
        }

        返回绑定;
    }

    受保护的虚拟MemberListBinding VisitMemberListBinding(MemberListBinding绑定)
    {
        IEnumerable的&LT; ElementInit&GT;初始化= this.VisitElementInitializerList(binding.Initializers);

        如果(初始化!= binding.Initializers)
        {
            返回前pression.ListBind(binding.Member,初始化);
        }

        返回绑定;
    }

    受保护的虚拟的IEnumerable&LT; ElementInit&GT; VisitElementInitializerList(ReadOnlyCollection还&LT; ElementInit&GT;原)
    {
        名单&LT; ElementInit&GT;名单= NULL;

        的for(int i = 0,N = original.Count;我n种;我++)
        {
            ElementInit的init = this.VisitElementInitializer([i]原);

            如果(名单!= NULL)
            {
                list.Add(INIT);
            }
            否则,如果(初始化!= [i]原)
            {
                名单=新的名单,其中,ElementInit&GT;(N);

                对于(INT J = 0; J&LT;我; J ++)
                {
                    list.Add(原[J]);
                }

                list.Add(INIT);
            }
        }

        如果(名单!= NULL)
        {
            返回列表;
        }

        回到原来的;
    }

    受保护的虚拟ElementInit VisitElementInitializer(ElementInit初始化)
    {
        ReadOnlyCollection还&LT;防爆pression&GT;参数= this.VisitEx pressionList(initializer.Arguments);

        如果(参数!= initializer.Arguments)
        {
            返回前pression.ElementInit(initializer.AddMethod,参数);
        }

        返回初始化;
    }
}
 

解决方案

在程序尝试用下面的替换撰写方法。

  {
    VAR地图= first.Parameters.Select((F,I)=&gt;新建{F,S = second.Parameters [I]})ToDictionary(P =&GT; PS,P =&GT; PF)。

    VAR secondRebound = ParameterRebinder.ReplaceParameters(地图,秒);

    返回前pression.Lambda&LT; T&GT;(合并(first.Body,secondRebound.Body),first.Parameters);
}
 

I am trying to get an understanding of expressions. I am hitting the dreaded "parameter was not bound in the specified LINQ to Entities query expression" exception. I have seen Skeet answer this before as well as others online. However I just cannot "see" the problem. I am using Colin Meek's example http://blogs.msdn.com/b/meek/archive/2008/05/02/linq-to-entities-combining-predicates.aspx and Matt Warren's VisitorExpression class http://blogs.msdn.com/b/mattwar/archive/2007/07/31/linq-building-an-iqueryable-provider-part-ii.aspx. I'm using a console app in VS 2010, framework 4.0. Sorry if this is beating a dead horse since it has been asked about before. Thanks for any help.

To be thorough, all the code is below:

class Program
{
    static void Main(string[] args)
    {
        Expression<Func<Car, bool>> theCarIsRed = c => c.Color == "Red";
        Expression<Func<Car, bool>> theCarIsCheap = c => c.Price < 10.0;
        Expression<Func<Car, bool>> theCarIsRedOrCheap = theCarIsRed.Or(theCarIsCheap);

        Car one = new Car() { CarId = 1, Color = "Red", Price = 10.0 };
        Car two = new Car() { CarId = 2, Color = "Blue", Price = 9.0 };
        Car three = new Car() { CarId = 3, Color = "Black", Price = 5.0 };
        Car four = new Car() { CarId = 4, Color = "Red", Price = 5.0 };

        EntityDBContext context = new EntityDBContext();
        context.CarEntity.Add(one);
        context.CarEntity.Add(two);
        context.CarEntity.Add(three);
        context.CarEntity.Add(four);

        using (var db = context)
        {
            // Bang
            var query = db.CarEntity.AsQueryable().Where(theCarIsRedOrCheap).ToList();

            foreach (var item in query)
            {
                Console.WriteLine(item.Color, item.Price);
            }
        }

        Console.ReadKey();
    }
}

public class Car 
{
    [Key]
    public int CarId { get; set; }
    public string Color { get; set; }
    public double Price { get; set; }
}


public static class Utility
{
    public static Expression<T> Compose<T>(this Expression<T> first,
        Expression<T> second, Func<Expression, Expression, Expression> merge)
    {
        var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f);

        var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);

        return Expression.Lambda<T>(merge(first.Body, second.Body), first.Parameters);
    }

    public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
    {
        return first.Compose(second, Expression.And);
    }

    public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
    {
        return first.Compose(second, Expression.Or);
    }
}


public class ParameterRebinder : ExpressionVisitor
{
    private readonly Dictionary<ParameterExpression, ParameterExpression> map;

    public ParameterRebinder(Dictionary<ParameterExpression, ParameterExpression> map)
    {
        this.map = map ?? new Dictionary<ParameterExpression, ParameterExpression>();
    }

    public static Expression ReplaceParameters(Dictionary<ParameterExpression, ParameterExpression> map, Expression exp)
    {
        return new ParameterRebinder(map).Visit(exp);
    }

    protected override Expression VisitParameter(ParameterExpression parmEx)
    {
        ParameterExpression replacement;
        if (map.TryGetValue(parmEx, out replacement))
        {
            parmEx = replacement;
        }

        return base.VisitParameter(parmEx);
    }
}

public abstract class ExpressionVisitor
{
    protected ExpressionVisitor()
    {
    }

    protected virtual Expression Visit(Expression exp)
    {
        if (exp == null)
        {
            return exp;
        }

        switch (exp.NodeType)
        {
            case ExpressionType.Negate:
            case ExpressionType.NegateChecked:
            case ExpressionType.Not:
            case ExpressionType.Convert:
            case ExpressionType.ConvertChecked:
            case ExpressionType.ArrayLength:
            case ExpressionType.Quote:
            case ExpressionType.TypeAs:
                return this.VisitUnary((UnaryExpression) exp);
            case ExpressionType.Add:
            case ExpressionType.AddChecked:
            case ExpressionType.Subtract:
            case ExpressionType.SubtractChecked:
            case ExpressionType.Multiply:
            case ExpressionType.MultiplyChecked:
            case ExpressionType.Divide:
            case ExpressionType.Modulo:
            case ExpressionType.And:
            case ExpressionType.AndAlso:
            case ExpressionType.Or:
            case ExpressionType.OrElse:
            case ExpressionType.LessThan:
            case ExpressionType.LessThanOrEqual:
            case ExpressionType.GreaterThan:
            case ExpressionType.GreaterThanOrEqual:
            case ExpressionType.Equal:
            case ExpressionType.NotEqual:
            case ExpressionType.Coalesce:
            case ExpressionType.ArrayIndex:
            case ExpressionType.RightShift:
            case ExpressionType.LeftShift:
            case ExpressionType.ExclusiveOr:
                return this.VisitBinary((BinaryExpression) exp);
            case ExpressionType.TypeIs:
                return this.VisitTypeIs((TypeBinaryExpression) exp);
            case ExpressionType.Conditional:
                return this.VisitConditional((ConditionalExpression) exp);
            case ExpressionType.Constant:
                return this.VisitConstant((ConstantExpression) exp);
            case ExpressionType.Parameter:
                return this.VisitParameter((ParameterExpression) exp);
            case ExpressionType.MemberAccess:
                return this.VisitMemberAccess((MemberExpression) exp);
            case ExpressionType.Call:
                return this.VisitMethodCall((MethodCallExpression) exp);
            case ExpressionType.Lambda:
                return this.VisitLambda((LambdaExpression) exp);
            case ExpressionType.New:
                return this.VisitNew((NewExpression) exp);
            case ExpressionType.NewArrayInit:
            case ExpressionType.NewArrayBounds:
                return this.VisitNewArray((NewArrayExpression) exp);
            case ExpressionType.Invoke:
                return this.VisitInvocation((InvocationExpression) exp);
            case ExpressionType.MemberInit:
                return this.VisitMemberInit((MemberInitExpression) exp);
            case ExpressionType.ListInit:
                return this.VisitListInit((ListInitExpression) exp);
            default:
                throw new Exception(String.Format("Unhandled expression type: '{0}'", exp.NodeType));

        }
    }

    protected virtual MemberBinding VisitBinding(MemberBinding binding)
    {
        switch (binding.BindingType)
        {
            case MemberBindingType.Assignment:
                return this.VisitMemberAssignment((MemberAssignment) binding);
                case MemberBindingType.MemberBinding:
                return this.VisitMemberMemberBinding((MemberMemberBinding) binding);
                case MemberBindingType.ListBinding:
                return this.VisitMemberListBinding((MemberListBinding) binding);
            default:
                throw new Exception(String.Format("Unhandled binding type '{0}'", binding.BindingType));
        }
    }

    protected virtual Expression VisitListInit(ListInitExpression init)
    {
        NewExpression n = this.VisitNew(init.NewExpression);
        IEnumerable<ElementInit> initializers = this.VisitElementInitializerList(init.Initializers);

        if (n != init.NewExpression || initializers != init.Initializers)
        {
            return Expression.ListInit(n, initializers);
        }

        return init;
    }

    protected virtual Expression VisitMemberInit(MemberInitExpression memberInitExpression)
    {
        NewExpression n = this.VisitNew(memberInitExpression.NewExpression);
        IEnumerable<MemberBinding> bindings = this.VisitBindingList(memberInitExpression.Bindings);

        if (n != memberInitExpression.NewExpression || bindings != memberInitExpression.Bindings)
        {
            return Expression.MemberInit(n, bindings);
        }

        return memberInitExpression;
    }

    protected virtual Expression VisitInvocation(InvocationExpression invocationExpression)
    {
        IEnumerable<Expression> args = this.VisitExpressionList(invocationExpression.Arguments);
        Expression expr = this.Visit(invocationExpression.Expression);

        if (args != invocationExpression.Arguments || expr != invocationExpression.Expression)
        {
            return Expression.Invoke(expr, args);
        }

        return invocationExpression;
    }

    protected virtual Expression VisitNewArray(NewArrayExpression newArrayExpression)
    {
        IEnumerable<Expression> exprs = this.VisitExpressionList(newArrayExpression.Expressions);

        if (exprs != newArrayExpression.Expressions)
        {
            if (newArrayExpression.NodeType == ExpressionType.NewArrayInit)
            {
                return Expression.NewArrayInit(newArrayExpression.Type.GetElementType(), exprs);
            }
            else
            {
                return Expression.NewArrayBounds(newArrayExpression.Type.GetElementType());
            }
        }

        return newArrayExpression;
    }

    protected virtual NewExpression VisitNew(NewExpression newExpression)
    {
        IEnumerable<Expression> args = this.VisitExpressionList(newExpression.Arguments);

        if (args != newExpression.Arguments)
        {
            if (newExpression.Members != null)
            {
                return Expression.New(newExpression.Constructor, args, newExpression.Members);
            }
            else
            {
                return Expression.New(newExpression.Constructor, args);
            }
        }

        return newExpression;
    }

    protected virtual Expression VisitLambda(LambdaExpression lambdaExpression)
    {
        Expression body = this.Visit(lambdaExpression.Body);
        if (body != lambdaExpression.Body)
        {
            return Expression.Lambda(lambdaExpression.Type, body, lambdaExpression.Parameters);
        }

        return lambdaExpression;
    }

    protected virtual Expression VisitMethodCall(MethodCallExpression methodCallExpression)
    {
        Expression obj = this.Visit(methodCallExpression.Object);
        IEnumerable<Expression> args = this.VisitExpressionList(methodCallExpression.Arguments);

        if (obj != methodCallExpression.Object || args != methodCallExpression.Arguments)
        {
            return Expression.Call(obj, methodCallExpression.Method, args);
        }

        return methodCallExpression;
    }

    protected virtual Expression VisitMemberAccess(MemberExpression memberExpression)
    {
        Expression exp = this.Visit(memberExpression.Expression);

        if (exp != memberExpression.Expression)
        {
            return Expression.MakeMemberAccess(exp, memberExpression.Member);
        }

        return memberExpression;
    }

    protected virtual Expression VisitParameter(ParameterExpression parameterExpression)
    {
        return parameterExpression;
    }

    protected virtual Expression VisitConstant(ConstantExpression constantExpression)
    {
        return constantExpression;
    }

    protected virtual Expression VisitConditional(ConditionalExpression conditionalExpression)
    {
        Expression test = this.Visit(conditionalExpression.Test);
        Expression ifTrue = this.Visit(conditionalExpression.IfTrue);
        Expression ifFalse = this.Visit(conditionalExpression.IfFalse);

        if (test != conditionalExpression.Test || ifTrue != conditionalExpression.IfTrue || ifFalse != conditionalExpression.IfFalse)
        {
            return Expression.Condition(test, ifTrue, ifFalse);
        }

        return conditionalExpression;
    }

    protected virtual Expression VisitTypeIs(TypeBinaryExpression typeBinaryExpression)
    {
        Expression expr = this.Visit(typeBinaryExpression.Expression);
        if (expr != typeBinaryExpression)
        {
            return Expression.TypeIs(expr, typeBinaryExpression.TypeOperand);
        }

        return typeBinaryExpression;
    }

    protected virtual Expression VisitBinary(BinaryExpression binaryExpression)
    {
        Expression left = this.Visit(binaryExpression.Left);
        Expression right = this.Visit(binaryExpression.Right);
        Expression conversion = this.Visit(binaryExpression.Conversion);

        if (left != binaryExpression.Left || right != binaryExpression.Right || conversion != binaryExpression.Conversion)
        {
            if (binaryExpression.NodeType == ExpressionType.Coalesce && binaryExpression.Conversion != null)
            {
                return Expression.Coalesce(left, right, conversion as LambdaExpression);
            }
            else
            {
                return Expression.MakeBinary(binaryExpression.NodeType, left, right, binaryExpression.IsLiftedToNull,
                                             binaryExpression.Method);
            }
        }

        return binaryExpression;
    }

    protected virtual Expression VisitUnary(UnaryExpression unaryExpression)
    {
        Expression operand = this.Visit(unaryExpression.Operand);
        if (operand != unaryExpression.Operand)
        {
            return Expression.MakeUnary(unaryExpression.NodeType, operand, unaryExpression.Type,
                                        unaryExpression.Method);
        }

        return unaryExpression;
    }

    protected virtual ReadOnlyCollection<Expression> VisitExpressionList(ReadOnlyCollection<Expression> original)
    {
        List<Expression> list = null;

        for (int i = 0, n = original.Count; i < n; i++)
        {
            Expression p = this.Visit(original[i]);
            if (list != null)
            {
                list.Add(p);
            }
            else if (p != original[i])
            {
                list = new List<Expression>(n);
                for (int j = 0; j < i; j++)
                {
                    list.Add(original[j]);
                }

                list.Add(p);
            }
        }

        return list != null ? list.AsReadOnly() : original;
    }

    protected virtual IEnumerable<MemberBinding> VisitBindingList(ReadOnlyCollection<MemberBinding> original)
    {
        List<MemberBinding> list = null;

        for (int i = 0, n = original.Count; i < n; i++)
        {
            MemberBinding b = this.VisitBinding(original[i]);

            if (list != null)
            {
                list.Add(b);
            }
            else if (b != original[i])
            {
                list = new List<MemberBinding>(n);

                for (int j = 0; j < i; j++)
                {
                    list.Add(original[j]);
                }

                list.Add(b);
            }
        }

        if (list != null)
        {
            return list;
        }

        return original;
    }

    protected virtual MemberAssignment VisitMemberAssignment(MemberAssignment assignment)
    {
        Expression e = this.Visit(assignment.Expression);

        if (e != assignment.Expression)
        {
            return Expression.Bind(assignment.Member, e);
        }

        return assignment;
    }

    protected virtual MemberMemberBinding VisitMemberMemberBinding(MemberMemberBinding binding)
    {
        IEnumerable<MemberBinding> bindings = this.VisitBindingList(binding.Bindings);

        if (bindings != binding.Bindings)
        {
            return Expression.MemberBind(binding.Member, bindings);
        }

        return binding;
    }

    protected virtual MemberListBinding VisitMemberListBinding(MemberListBinding binding)
    {
        IEnumerable<ElementInit> initializers = this.VisitElementInitializerList(binding.Initializers);

        if (initializers != binding.Initializers)
        {
            return Expression.ListBind(binding.Member, initializers);
        }

        return binding;
    }

    protected virtual IEnumerable<ElementInit> VisitElementInitializerList(ReadOnlyCollection<ElementInit> original)
    {
        List<ElementInit> list = null;

        for (int i = 0, n = original.Count; i < n; i++)
        {
            ElementInit init = this.VisitElementInitializer(original[i]);

            if (list != null)
            {
                list.Add(init);
            }
            else if (init != original[i])
            {
                list = new List<ElementInit>(n);

                for (int j = 0; j < i; j++)
                {
                    list.Add(original[j]);
                }

                list.Add(init);
            }
        }

        if (list != null)
        {
            return list;
        }

        return original;
    }

    protected virtual ElementInit VisitElementInitializer(ElementInit initializer)
    {
        ReadOnlyCollection<Expression> arguments = this.VisitExpressionList(initializer.Arguments);

        if (arguments != initializer.Arguments)
        {
            return Expression.ElementInit(initializer.AddMethod, arguments);
        }

        return initializer;
    }
}

解决方案

In utility try replacing the compose method with the following.

{
    var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f);

    var secondRebound = ParameterRebinder.ReplaceParameters(map, second);

    return Expression.Lambda<T>(merge(first.Body, secondRebound.Body), first.Parameters);
}

这篇关于可怕的&QUOT;参数没有被绑定在指定的LINQ to Entities查询EX pression&QUOT;例外的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆