问题描述
我之前使用过基于 lamdas 的 C# 表达式,但我没有手工编写它们的经验.给定一个 Expression
,我想创建一个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#如何转换一个表达式<Func<SomeType>>到表达式<Func<OtherType>>的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!