【发布时间】:2015-09-25 14:13:44
【问题描述】:
我觉得我遗漏了一些简单的东西,但我还没有找到回答我问题的文档。
我最近一直在将一些 linq 投影分解为可重用的表达式。它在对集合进行操作时效果很好,但我似乎无法弄清楚如何将表达式应用于另一个表达式中的单个对象。下面是我想要完成的一个例子:
public class Person
{
public string ID { get; set; }
public string Name { get; set; }
}
public class PersonDto
{
public string ID { get; set; }
public string Name { get; set; }
}
public class Department
{
Person Manager { get; set; }
List<Person> Employees { get; set; }
}
public class DepartmentDto
{
PersonDto Manager { get; set; }
List<PersonDto> Employees { get; set; }
}
public Expression<Func<Person, PersonDto>> CreatePersonDto = p => new PersonDto
{
ID = p.ID,
Name = p.Name
};
public Expression<Func<Department, DepartmentDto>> CreateDepartmentDto = d => new DepartmentDto
{
Manager = d.Manager // How do I transform this `Person` using `CreatePersonDto`
Employees = d.Employees.Select(CreatePersonDto) //Does not work either
};
编辑:需要明确的是,我正在使用需要使用此表达式生成 SQL 语句的 Linq-to-Entities。因此,我无法将 Compile 表达式转换为 Func,因为我可能能够使用 Linq-to-Objects。
【问题讨论】:
-
CreatePersonDto将Person转换为PersonDto,但Manager类型为Person,您将无法将PersonDto分配给Person变量(这就是你想要在Manager = // How do I....中做的事情 -
我的示例中有一个错误。我已经修改了它。 DepartmentDto 应该由 PersonDto 和 List
组成。感谢您指出@codroipo -
第二行
Employees = d.Employees.Select(CreatePersonDto)是否有任何错误?它对我有用。 IIRC 不可能那么容易地在表达式中使用表达式。您必须使用Expression类上的静态方法手动创建表达式。 -
@Mayoor 你可能是对的。现在我已经仔细查看了我的实际源代码(而不是我匆忙创建的示例),我看到我将
CreatePersonDto的等价物传递给了 DbSet 上的表达式之外的Select。示例:dbSet.Select(CreatePersonDto)。它似乎在表达式的上下文中不起作用。 -
我在使用
Compile时遇到的问题是,虽然它适用于 Linq to Objects,但不适用于 Linq to Entities。 Linq to Entities 需要评估最终转换为 SQL 查询的表达式。它无法将Func<Person, PersonDto>评估为 sql
标签: c# entity-framework linq-to-entities linq-expressions