如何将linq中的select子句与实体结合起来以投射到匿名类型?
假设我有这些实体:
public class Address
{
public string City { get; set; }
public int ZipCode { get; set; }
//other properties
}
public class Person
{
public string Name { get; set; }
public Address Address { get; set; }
//a LOT of other properties
}
//extend person class with employee specific properties
public class Employee : Person
{
public double Salary { get; set; }
public Person Manager { get; set; }
}
有时我只需要请求Person类的少数属性:
Context.Persons.Where(...).Select(p => new
{
p.Name,
PersonCity = p.Address.City,
//other needed properties
});
我还需要请求我的Employee类的相同属性以及特定属性:
Context.Employees.OfType<Employee>().Where(...).Select(e => new
{
e.Salary,
ManagerName = e.Manager.Name,
e.Name,
PersonCity = e.City.Name,
//other needed properties identical as the previous select with Person entity
});
表达式树操作(或其他解决方案)是否可以组合两个select子句,以便不复制Person实体中的所有select子句?
类似的东西:
var personSelect = p => new {
p.Name,
PersonCity = p.Address.City,
//other needed properties
};
var employeeSelect = personSelect.Combine(e => new {
e.Salary,
ManagerName = e.Manager.Name
});
context.Employees.OfType<Employee>().Where(...).Select(employeeSelect).FirstOrDefault();
// returns an anonymous object
// {
// Name = "Joachim",
// PersonCity = "Lyon",
// <other Person properties>
// Salary = 65432.10,
// ManagerName = "Samuel"
// }
答案 0 :(得分:2)
不,没有办法完全按照你的要求去做。问题是必须在编译时创建每个匿名类型,但表达式树在运行时工作。
我可以通过两种方式解决这个问题:
Employee
的匿名类型会有一个名为PersonData
的属性,其中包含匿名类型,其中包含来自Person
的信息。PersonData
和EmployeeData
(继承自PersonData
)。每种类型都可以为您创建表达式,EmployeeData
的表达式将根据PersonData
的表达式计算。在这两种情况下,你都需要一些表达树管道,但它不应该那么难。