1

假设我有以下 EF 代码:

context.Employees.Select(e => e
{
    FullName = e.FirstName + " " + e.LastName,
    StartDate = e.StartDate,
    ... // Grab other data
};

现在,也许我注意到我在多个地方构建了全名,但希望集中。有可能重构这个吗?

如果我将其设为方法或 Func,则会出现 EF 错误,因为它无法将其转换为 SQL。

注意:这是一个简单的示例,假设在分配中使用“Select”、“Where”等任何内容都会变得更加复杂,因此添加 ToList 然后运行其他代码将不是最佳的,并且不符合重构,因为我必须改变功能,而不仅仅是让它更易于维护。

4

2 回答 2

0

一种解决方案是使用LinqKitAsExpandable中的方法:

Expression<Func<Employee,string>> fullName = e => e.FirstName + " " + e.LastName;
context.Employees.AsExpandable().Select(e => e
{
    FullName = fullName.Compile().Invoke(e),
    StartDate = e.StartDate,
    ... // Grab other data
};

从链接的文章:

Compile 是 Expression 类中的内置方法。它将表达式转换为满足编译器的普通 Func。当然,如果这个方法实际运行,我们最终会得到编译的 IL 代码而不是表达式树,并且 LINQ to SQL 或实体框架会抛出异常。但这是聪明的部分:编译从来没有真正运行过;LINQ to SQL 或实体框架也没有看到它。对 Compile 的调用被一个通过调用 AsExpandable 创建的特殊包装器完全剥离,并替换为正确的表达式树。

或者,您可以考虑使用实体框架创建模型定义函数。如果要在 Employee 类本身上定义 FullName 属性,还有Microsoft.Linq.Translations库。

于 2012-11-14T23:32:12.020 回答
0

我认为在实体类本身中实现它的更好的集中方式。您可以将 ReadOnly 属性添加到您的实体类中,该属性应该是NotMapped数据库以返回所需的格式化数据。

Public class Employee
{
//...

public string fullName{get { return  FirstName + " " + LastName;}}
}
于 2012-11-15T03:36:27.640 回答