转换表达式<Func<T1,bool>>到表达式<Func<T2,bool>> [英] Convert Expression<Func<T1, bool>> to Expression<Func<T2, bool>>

查看:76
本文介绍了转换表达式<Func<T1,bool>>到表达式<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>,但我不能这样做.是否可以进行表达式的转换?注意 User 和 UserDTO 有相同的 props.

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).

这篇关于转换表达式&lt;Func&lt;T1,bool&gt;&gt;到表达式&lt;Func&lt;T2,bool&gt;&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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