转换表达式<Func<T1,bool>>到表达式<Func<T2,bool>> [英] Convert Expression<Func<T1, bool>> to Expression<Func<T2, bool>>
问题描述
我正在使用存储库模式.T1 是 T2 的 Dto(例如:UserDto 和 User)
I am using repository pattern. T1 is the Dto of T2 (e.x: UserDto and User)
在service层,我通过Expression
In the service layer, I pass Expression<Func<UserDto, bool>> as a parameter to a method, which in itself calls a method in the data-access layer in which it passes Expression<Func<User, bool>>.
现在,您可能会问我为什么不一直使用 Expression
Now, you might ask me why don't I just use Expression<Func<User, bool>> all the way but I can't do that. Is it possible to do the conversion of the Expression? Note that User and UserDTO have the same props.
推荐答案
可以,只要您有将 T2 转换为 T1 的方法.这是一个简单的玩具示例,其中 T2 是 string
而 T1 是 int
:
Yes, as long as you have a method that converts T2 into T1. Here is a simple toy example where T2 is string
and T1 is int
:
// That's the conversion function from T2 to T1
private static int stringToInt(string s) => s.Length;
[TestMethod]
public void Test()
{
// We want to convert this into string->bool
Expression<Func<int, bool>> isEven = i => i % 2 == 0;
MethodInfo stringToIntMethod = ((Func<string, int>) (stringToInt)).Method;
ParameterExpression x = Expression.Parameter(typeof(string));
// That's the converted expression
Expression<Func<string, bool>> converted =
Expression.Lambda<Func<string, bool>>(
Expression.Invoke(isEven,
Expression.Call(null, stringToIntMethod, x)), x);
// Check that it works as expected:
converted.Compile().Invoke("aa").Should().BeTrue();
converted.Compile().Invoke("aaa").Should().BeFalse();
}
如果您打算将表达式与 LINQ 提供程序(例如实体框架或 Cosmos DB)一起使用,您必须确保支持包括转换调用在内的整个表达式.如果它是您定义的方法,则通常不会出现这种情况.
If you intend to use the expression with a LINQ provider (e.g. Entity Framework or Cosmos DB), you must make sure that the entire expression including the conversion call is supported. This is usually not the case if it is a method that you defined.
如果这有问题,您能否在 T1 和 T2 上强加一个通用接口或基类?在这种情况下,您可以在两个层上传递 Expression
类型的表达式而无需转换.否则(例如,如果 T1 和 T2 完全不同)实现您想要的唯一方法是分析表达式的结构并构建自定义表达式转换器(例如使用 ExpressionVisitor
).
If that should be problem, can you impose a common interface or base class on both T1 and T2? In that case you could pass an expression of type Expression<Func<BaseClass, bool>>
on both layers without conversion. Failing that (e.g. if T1 and T2 are completely different) the only way to achieve what you want is to analyze the structure of the expression and build a custom expression converter (e.g. using ExpressionVisitor
).
这篇关于转换表达式<Func<T1,bool>>到表达式<Func<T2,bool>>的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!