Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.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# 组合两个不同类型的谓词_C#_Expression_Predicate_Linq Expressions_Predicatebuilder - Fatal编程技术网

C# 组合两个不同类型的谓词

C# 组合两个不同类型的谓词,c#,expression,predicate,linq-expressions,predicatebuilder,C#,Expression,Predicate,Linq Expressions,Predicatebuilder,我通过地址模型(expressionaddresspred)构建了一个谓词。现在我想将其与Person模型的谓词(Expression personPred)结合起来。这些模型的示例如下: public class Person { public string Name { get; set; } public Address Address { get; set; } } public class Address { public string StreetName {

我通过地址模型(
expressionaddresspred
)构建了一个谓词。现在我想将其与Person模型的谓词(
Expression personPred
)结合起来。这些模型的示例如下:

public class Person
{
    public string Name { get; set; }
    public Address Address { get; set; }
}
public class Address
{
    public string StreetName { get; set; }
}
如果我做了类似的事情

addressPred = addressPred.And(a => a.StreetName == "Foo bar");
然后将其与personPred组合,组合谓词将有一个与

combinedPred = combinedPred.And(a => a.Address.StreetName == "Foo bar");
组合谓词的类型为
Person

我怎样才能做到这一点

编辑: 实际上,为了简单起见,模型要大得多,而且要缩短。我最终想要实现的是构建一次Address谓词,然后为Person构建一个具有自身条件的谓词,然后将其组合成一个谓词,其中Person谓词的Address部分来自Address谓词(Address是Person的属性)。我之所以想这样做,是因为Address可能有很多条件,我想在进行db调用(到Person、Company、Customer等)之前,将其用作其他谓词(Person,稍后还有Company、Customer等)的一部分

另外,代码的
combinedPred
行仅显示来自地址谓词的
combinedPred
的等价语句

这种情况是,构建的
表达式addressPred
的地址为
参数Expression
,需要将表达式应用于
成员表达式。因此,我建议将
参数表达式
替换为
成员表达式
,如下所示:

var personParameter = Expression.Parameter(typeof(Person), "person");
var addressProperty = Expression.PropertyOrField(personParameter, "Address");        
var combined = new ReplaceVisitor<Address>(addressProperty).Visit(addressPred.Body);
var result = Expression.Lambda<Func<Person, bool>>(combined, personParameter);
var personParameter=Expression.Parameter(typeof(Person),“Person”);
var addressProperty=Expression.PropertyOrField(personParameter,“Address”);
var组合=新的替换访问者(addressProperty).Visit(addressPred.Body);
var结果=表达式.Lambda(组合,personParameter);
其中:

public class ReplaceVisitor<T> : ExpressionVisitor
{
    private readonly MemberExpression _replacement;

    public ReplaceVisitor(MemberExpression replacement)
    {
        _replacement = replacement;
    }

    protected override Expression VisitParameter(ParameterExpression node)
    {
        return node.Type.IsAssignableFrom(typeof(T))
                ? _replacement : base.VisitParameter(node);
    }
}
public类替换访问者:ExpressionVisitor
{
私有只读成员表达式\u替换;
公共替换访问者(成员表达式替换)
{
_替换=替换;
}
受保护的重写表达式VisitParameter(ParameterExpression节点)
{
返回node.Type.IsAssignableFrom(typeof(T))
?_替换:基本访问参数(节点);
}
}

情况是,构建的
表达式addressPred
的地址为
参数Expression
,需要将表达式应用于
成员表达式。因此,我建议将
参数表达式
替换为
成员表达式
,如下所示:

var personParameter = Expression.Parameter(typeof(Person), "person");
var addressProperty = Expression.PropertyOrField(personParameter, "Address");        
var combined = new ReplaceVisitor<Address>(addressProperty).Visit(addressPred.Body);
var result = Expression.Lambda<Func<Person, bool>>(combined, personParameter);
var personParameter=Expression.Parameter(typeof(Person),“Person”);
var addressProperty=Expression.PropertyOrField(personParameter,“Address”);
var组合=新的替换访问者(addressProperty).Visit(addressPred.Body);
var结果=表达式.Lambda(组合,personParameter);
其中:

public class ReplaceVisitor<T> : ExpressionVisitor
{
    private readonly MemberExpression _replacement;

    public ReplaceVisitor(MemberExpression replacement)
    {
        _replacement = replacement;
    }

    protected override Expression VisitParameter(ParameterExpression node)
    {
        return node.Type.IsAssignableFrom(typeof(T))
                ? _replacement : base.VisitParameter(node);
    }
}
public类替换访问者:ExpressionVisitor
{
私有只读成员表达式\u替换;
公共替换访问者(成员表达式替换)
{
_替换=替换;
}
受保护的重写表达式VisitParameter(ParameterExpression节点)
{
返回node.Type.IsAssignableFrom(typeof(T))
?_替换:基本访问参数(节点);
}
}

根本不清楚你在问什么。
personPred
在哪里适合所有这些?
combinedPred
似乎没有使用它,它有自己的逻辑来获取
地址
对象。请改进您的问题,使其有意义。您需要将与地址相关的谓词包装为与人相关的谓词,例如
p=>addressPred(p.address)
。另外,确保你发布了事情的实际类型,以及你想要完成的一个例子。现在有很多未知的类型和手工操作,因此您的确切要求有点不清楚。注意:@Lasse的上述建议在语法上是正确的,但没有使用任何
表达式,即
Person
谓词。根据定义,谓词返回一个
bool
值。在你的问题中没有任何东西可以解释你所说的“合并”的意思,以至于最后的谓词只有一个布尔表达式,并且根本不使用任何接受
Person
的谓词。我已经编辑了这个问题。希望现在我问的更清楚,你问的根本不清楚。
personPred
在哪里适合所有这些?
combinedPred
似乎没有使用它,它有自己的逻辑来获取
地址
对象。请改进您的问题,使其有意义。您需要将与地址相关的谓词包装为与人相关的谓词,例如
p=>addressPred(p.address)
。另外,确保你发布了事情的实际类型,以及你想要完成的一个例子。现在有很多未知的类型和手工操作,因此您的确切要求有点不清楚。注意:@Lasse的上述建议在语法上是正确的,但没有使用任何
表达式,即
Person
谓词。根据定义,谓词返回一个
bool
值。在你的问题中没有任何东西可以解释你所说的“合并”的意思,以至于最后的谓词只有一个布尔表达式,并且根本不使用任何接受
Person
的谓词。我已经编辑了这个问题。希望现在能更清楚地知道我在问什么。这正是我想要的!谢谢!:)正是我要找的!谢谢!:)