组合两个不同类型的谓词
Combine two predicates of different type
我已经通过地址模型构建了一个谓词 (Expression<Func<Address, bool>> addressPred
)。现在我想将它与 Person 模型的谓词结合起来 (Expression<Func<Person, bool>> 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");
combinedPredicate 的类型为 Person
。
我怎样才能做到这一点?
编辑:
实际上,模型要大得多,并且为了简单起见被缩短了。我最终想要实现的是一次构建 Address 谓词,然后为 Person 构建一个具有自己条件的谓词,然后将其组合成一个谓词,其中 Person 谓词的 Address-part 来自 Address 谓词(Address 是 属性 的人)。我想这样做的原因是因为 Address 可能有很多条件,我想在进行数据库调用(对 Person,公司、客户等)
此外,combinedPred
行代码仅用于显示来自 Address 谓词的 combinedPred
的等式语句。
情况是构建的Expression<Func<Address, bool>> addressPred
地址为ParameterExpression
,需要将表达式应用到MemberExpression
。所以我可以建议用 MemberExpression
替换 ParameterExpression
像这样:
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);
其中:
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);
}
}
我已经通过地址模型构建了一个谓词 (Expression<Func<Address, bool>> addressPred
)。现在我想将它与 Person 模型的谓词结合起来 (Expression<Func<Person, bool>> 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");
combinedPredicate 的类型为 Person
。
我怎样才能做到这一点?
编辑:
实际上,模型要大得多,并且为了简单起见被缩短了。我最终想要实现的是一次构建 Address 谓词,然后为 Person 构建一个具有自己条件的谓词,然后将其组合成一个谓词,其中 Person 谓词的 Address-part 来自 Address 谓词(Address 是 属性 的人)。我想这样做的原因是因为 Address 可能有很多条件,我想在进行数据库调用(对 Person,公司、客户等)
此外,combinedPred
行代码仅用于显示来自 Address 谓词的 combinedPred
的等式语句。
情况是构建的Expression<Func<Address, bool>> addressPred
地址为ParameterExpression
,需要将表达式应用到MemberExpression
。所以我可以建议用 MemberExpression
替换 ParameterExpression
像这样:
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);
其中:
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);
}
}