3

我如何将 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"
// }
4

1 回答 1

3

不,没有办法完全按照您的要求进行。问题是每个匿名类型都必须在编译时创建,但表达式树在运行时工作。

我可以看到两种解决方法:

  1. 您的匿名类型 forEmployee将有一个类似于 的属性PersonData,其中包含来自 的信息的匿名类型Person
  2. 您将创建普通类型,例如PersonDataand EmployeeData(继承自PersonData)。每种类型都可以为您提供一个表达式来创建它,并且EmployeeData' 表达式将根据PersonData' 表达式计算。

在这两种情况下,您都需要一些表达式树管道,但这应该不难做到。

于 2013-06-21T13:38:44.587 回答