Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# “该参数未绑定在指定的LINQ到实体查询表达式中。”规范模式和_C#_Entity Framework_Linq_Linq To Sql_Linq Expressions - Fatal编程技术网

C# “该参数未绑定在指定的LINQ到实体查询表达式中。”规范模式和

C# “该参数未绑定在指定的LINQ到实体查询表达式中。”规范模式和,c#,entity-framework,linq,linq-to-sql,linq-expressions,C#,Entity Framework,Linq,Linq To Sql,Linq Expressions,我遵循描述的规范模式实现。我有一个如下所示的存储库方法: 公共IEnumerable FindSpecification规范 { 返回myDbContext.MyDtos.Wherespecification.ToExpression.Take20.ToList; } 如果我使用普通的非复合规范,它可以正常工作,但以下场景失败,消息是参数“r”未绑定到指定的LINQ to Entities查询表达式中: 规格规格=新规格1某些标准 .和新规范2部分标准 .和新规范3部分标准 //等等。。。 va

我遵循描述的规范模式实现。我有一个如下所示的存储库方法:

公共IEnumerable FindSpecification规范 { 返回myDbContext.MyDtos.Wherespecification.ToExpression.Take20.ToList; } 如果我使用普通的非复合规范,它可以正常工作,但以下场景失败,消息是参数“r”未绑定到指定的LINQ to Entities查询表达式中:

规格规格=新规格1某些标准 .和新规范2部分标准 .和新规范3部分标准 //等等。。。 var myDtos=回购金融资产; 从我目前所读到的内容来看,这与参数引用对所有表达式都不相同有关,但我不确定如何解决这个问题

作为参考,以下是AndSpecification类在我的代码中的样子:

公共类和规范:规范 { 私有只读规范_左; 私有只读规范_right; 公共和规格规格左,规格右 { _左=左; _右=右; } 公共重写表达式ToExpression { 表达式leftExpression=_left.ToExpression; 表达式rightExpression=_right.ToExpression; BinaryExpression和Expression=Expression.AndAlso leftExpression.Body,rightExpression.Body; 返回表达式.Lambda andExpression,leftExpression.Parameters.Single; } } 问题在于您的ToExpression方法

leftExpression和rightExpression都是LambdaExpression,并且都有各自不同的T参数

当您创建从ToExpression返回的LambdaExpression时,您会说这应该使用leftExpression中的参数。但是rightExpression中使用的参数呢?rightExpression.Body包含使用rightExpression.Parameters[0]的表达式,即使在获取rightExpression.Body并将其放入另一个表达式中之后,它们仍将继续引用对象rightExpression.Parameters[0]

您需要重写rightExpression以使用与leftExpression相同的参数。最简单的方法是使用ExpressionVisitor

首先,创建一个简单地将一个参数替换为另一个参数的:

public class ParameterReplaceVisitor : ExpressionVisitor
{
    private readonly ParameterExpression target;
    private readonly ParameterExpression replacement;

    public ParameterReplaceVisitor(ParameterExpression target, ParameterExpression replacement) =>
        (this.target, this.replacement) = (target, replacement);

    protected override Expression VisitParameter(ParameterExpression node) =>
        node == target ? replacement : base.VisitParameter(node);
}
然后使用此选项重写rightExpression.Body,使其使用与leftExpression相同的参数对象:

问题在于您的ToExpression方法

leftExpression和rightExpression都是LambdaExpression,并且都有各自不同的T参数

当您创建从ToExpression返回的LambdaExpression时,您会说这应该使用leftExpression中的参数。但是rightExpression中使用的参数呢?rightExpression.Body包含使用rightExpression.Parameters[0]的表达式,即使在获取rightExpression.Body并将其放入另一个表达式中之后,它们仍将继续引用对象rightExpression.Parameters[0]

您需要重写rightExpression以使用与leftExpression相同的参数。最简单的方法是使用ExpressionVisitor

首先,创建一个简单地将一个参数替换为另一个参数的:

public class ParameterReplaceVisitor : ExpressionVisitor
{
    private readonly ParameterExpression target;
    private readonly ParameterExpression replacement;

    public ParameterReplaceVisitor(ParameterExpression target, ParameterExpression replacement) =>
        (this.target, this.replacement) = (target, replacement);

    protected override Expression VisitParameter(ParameterExpression node) =>
        node == target ? replacement : base.VisitParameter(node);
}
然后使用此选项重写rightExpression.Body,使其使用与leftExpression相同的参数对象:


哪一行代码引发异常?您向我们展示了那行代码了吗?如果您包括包含正在抛出的行的代码部分,以及异常的完整堆栈跟踪,可能会有所帮助。它使用的参数是什么?实体属性是什么?谢谢你的评论。请检查已接受的答案以获得解决方案。每个规范的表达式使用的参数是DTO本身。问题是,表达式之间的参数不相同,尽管名称相同。解决方案是确保在所有链式表达式中使用左端表达式的参数。哪一行代码引发异常?您向我们展示了那行代码了吗?如果您包括包含正在抛出的行的代码部分,以及异常的完整堆栈跟踪,可能会有所帮助。它使用的参数是什么?实体属性是什么?谢谢你的评论。请检查已接受的答案以获得解决方案。每个规范的表达式使用的参数是DTO本身。问题是,表达式之间的参数不相同,尽管名称相同。解决方案是确保在所有链式表达式中使用左端表达式的参数。一件事,它不应该是visitor.VisitTrightExpression.Body吗?一件事,它不应该是visitor.VisitTrightExpression吗 身体