首页 > 解决方案 > 创建仅定义 lambda 主体的表达式树

问题描述

如标题所述 - 我想定义一个表达式,它只描述方法的主体。例子:

// Definition
public Expression<T> SomeExpression<T>() { ... }

// Usage
entities.Select(e => e.SomeExpression<int>())

// Instead of 
entities.Select(SomeExpression<int>())

我知道我可以将委托表达式定义为

Expression<Func<int>> SomeExpression() { ... }

但由于这描述了一个全脂代表,我必须将其用作.Select(SomeExpression()). 这是一个问题,因为我可以无缝使用它的唯一方法是附加SomeExpression到实体实例本身。

我知道这没有什么意义——简而言之,我正在尝试为项目中很久以前犯的一个愚蠢错误实施一种解决方法。适当的修复是不可能的。

评论:

更多信息

我正在尝试解决一个糟糕的继承问题 - 我有一个实体(Training ),它具有另一个实体( Course )的外键。训练实体由一个基类(同名 - Training)和几个派生类(Instances)组成。问题是对所有人来说都完全一样的外键保存在派生类的属性中,而不是基类中。因为我有一个公共服务层,所以每次我得到一个Training实体时,我都必须对所有派生类执行几个条件转换,才能到达Course实体。

SomeExpression本身有效地转化为类似的东西

t => t is InternalInstance
    ? (t as InternalInstance).Course,
    : t is OpenInstance
         ? // So on an so forth...

您可以在本主题中阅读更多详细信息。

为什么 lambda 在我的情况下不起作用?为了简单起见,我在问题中省略了泛型,但是在我的情况下SomeExpression,它的类必须依赖于几个泛型参数,因为我的解决方案中有几个 Web 项目,每个项目都有自己的课程实例类型。

这就是为什么这个表达式的理想位置是在Training类型上 - 它已经具有所需的通用参数。如果我不把它放在那里,我必须创建一个服务并使用容器来解决它们。然后我将不得不在任何我想使用这个映射的地方注入这个服务——主要是公共服务和视图模型。将其添加到公共服务中不是问题,但会很突兀,因为您需要额外的依赖关系,只是为了执行映射。视图模型是有问题的,因为它们使用AutoMapper配置来封装映射并将其保存在内部。自动映射器在容器启动并运行之前创建和缓存映射,这在NullReference中解析。有一些方法可以提供服务运行时,但这会增加视图模型和控制器中的样板。此时使用表达式获取Course比较麻烦,然后方便。

这就是上下文。我试图保持简短,但有很多障碍。

标签: c#delegatesexpression-trees

解决方案


推荐阅读