如标题所述-我想定义一个表达式,该表达式仅描述方法的主体。示例:
// 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
。
我知道这没有什么意义-简而言之,我正在尝试为项目中很久以前犯的一个愚蠢错误实施一种变通方法。正确的修复是不可能的。
备注:
SomeExpression
必须在实体实例e
中定义SomeExpression
必须在e
上运行(我在想Expression.Consntant(this)
)SomeExpression
必须受 EntityFramework SomeExpression
必须返回通用值,例如string
或int
我正在尝试解决继承性差的问题-我有一个实体( Training ),该实体具有指向另一个实体的外键( Course )。培训实体由一个基类(同名 Training )和几个派生类( Instances )组成。问题在于,外键对于所有人来说都是绝对相同的,它被保存在派生类的属性中,而不是基类中。由于我具有公共服务层,因此每次获得 Training 实体时,我都必须对所有派生类执行几次条件转换,以获取 Course 实体
SomeExpression
本身可以有效地翻译成类似的内容
t => t is InternalInstance
? (t as InternalInstance).Course,
: t is OpenInstance
? // So on an so forth...
您可以在this topic中阅读更多详细信息。
在我的情况下,lambda为什么不起作用?为了简单起见,我在该问题中省略了泛型,但是在我的情况下,SomeExpression
及其类必须依赖于几个泛型参数,因为我的解决方案中有多个Web项目,每个Web项目都有自己的课程和实例类型。
这就是为什么此表达式的理想位置应该是 Training 类型的原因-它已经具有必需的通用参数。如果我不把它放在那儿,则必须创建一个服务并使用容器来解决它们。然后,我将不得不在要使用此映射的任何地方注入该服务-主要是常见的服务和视图模型。将其添加到通用服务不是问题,但是很麻烦,因为您需要附加的依赖关系才能执行映射。 视图模型存在问题,因为它们使用 AutoMapper 配置来封装映射并将其保留在内部。 AutoMapper 会在容器启动并运行之前创建并缓存地图,该解析在 NullReference 中进行。有多种方法可以提供服务运行时,但是这会增加视图模型和控制器中的样板。此时,使用表达式获取 Course 更加麻烦,然后便便了。
这就是上下文。我试图使它简短,但是有很多障碍。