C#如何转换一个表达式<Func<SomeType>>到表达式<Func<OtherType>> [英] C# How to convert an Expression<Func<SomeType>> to an Expression<Func<OtherType>>

查看:25
本文介绍了C#如何转换一个表达式<Func<SomeType>>到表达式<Func<OtherType>>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我之前使用过基于 lamdas 的 C# 表达式,但我没有手工编写它们的经验.给定一个 Expression>originalPredicate,我想创建一个Expression>翻译谓词.

I have used C# expressions before based on lamdas, but I have no experience composing them by hand. Given an Expression<Func<SomeType, bool>> originalPredicate, I want to create an Expression<Func<OtherType, bool>> translatedPredicate.

在这种情况下 SomeType 和 OtherType 具有相同的字段,但它们不相关(没有继承,也不是基于公共接口).

In this case SomeType and OtherType have the same fields, but they are not related (no inheritance and not based on a common interface).

背景:我有一个基于 LINQ to SQL 的存储库实现.我将 LINQ to SQL 实体投影到我的模型实体,以将我的模型保存在 POCO 中.我想将表达式传递给存储库(作为规范的一种形式),但它们应该基于模型实体.但我无法将这些表达式传递给数据上下文,因为它需要基于 LINQ to SQL 实体的表达式.

Background: I have a repository implementation based on LINQ to SQL. I project the LINQ to SQL entities to my Model entities, to keep my model in POCO. I want to pass expressions to the repository (as a form of specifications) but they should be based on the model entities. But I can't pass those expressions to the data context, since it expects expressions based on the LINQ to SQL entities.

推荐答案

Expression,最简单的方法就是用一个转换表达式:

With Expression, the simplest way is with a conversion expression:

class Foo {
    public int Value { get; set; }
}
class Bar {
    public int Value { get; set; }
}
static class Program {
    static void Main() {
        Expression<Func<Foo, bool>> predicate =
            x => x.Value % 2 == 0;
        Expression<Func<Bar, Foo>> convert =
            bar => new Foo { Value = bar.Value };

        var param = Expression.Parameter(typeof(Bar), "bar");
        var body = Expression.Invoke(predicate,
              Expression.Invoke(convert, param));
        var lambda = Expression.Lambda<Func<Bar, bool>>(body, param);

        // test with LINQ-to-Objects for simplicity
        var func = lambda.Compile();
        bool withOdd = func(new Bar { Value = 7 }),
             withEven = func(new Bar { Value = 12 });
    }
}

但是请注意,不同的提供商会对此提供不同的支持.例如,EF 可能不喜欢它,即使 LINQ-to-SQL 喜欢.

Note however that this will be supported differently by different providers. EF might not like it, for example, even if LINQ-to-SQL does.

另一种选择是完全重建表达式树,使用反射找到对应的成员.复杂得多.

The other option is to rebuild the expression tree completely, using reflection to find the corresponding members. Much more complex.

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

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