C#如何转换的表达式来; Func键<&SOMETYPE GT;>一个表达式来; Func键<&OTHERTYPE GT;>
我已经使用基于lamdas之前,C#则表达式,但我没有经验用手将它们组成。给定一个表达式来; Func键< SOMETYPE,布尔>> originalPredicate
,我想创建一个表达式来; Func键< OTHERTYPE,布尔>> translatedPredicate
。
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到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.
随着表达式
,最简单的方法是用一个转换的表达式
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到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.