How do I reuse an Expression on a single object in

2020-04-23 04:50发布

I feel like I am missing something simple, but I have not found the documentation that answers my question.

I have recently been decomposing some of the linq projections into reusable expressions. It works great when operating on a collection, but I can't seem to figure out how to apply an expression to a single object in another expression. Below is an example of what I am trying to accomplish:

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
};

EDIT: To be clear, I am using Linq-to-Entities that needs to use this Expression to generate a SQL statement. As a result, I cannot Compile the expression to a Func as I might be able to using Linq-to-Objects.

2条回答
【Aperson】
2楼-- · 2020-04-23 05:23

You can:

public static Expression<Func<Department, DepartmentDto>> CreateDepartmentDto = d =>
     new DepartmentDto
        {
            Manager = CreatePersonDto.Compile()(d.Manager),
            Employees = d.Employees.Select(CreatePersonDto.Compile()).ToList() // Or declare Employees as IEnumerable and avoid ToList conversion
        };

Clearly, instead of calling two times Compile method you can store the compiled Func

查看更多
不美不萌又怎样
3楼-- · 2020-04-23 05:48

You can use LINQKit to expand the expressions that you have within other expressions:

private static Expression<Func<Department, DepartmentDto>> CreateDepartmentDtoUnexpanded = d => new DepartmentDto
{
    Manager = CreatePersonDto.Invoke(d.Manager),
    Employees = d.Employees.Select(employee => CreatePersonDto.Invoke(employee))
        .ToList(),
};
public static Expression<Func<Department, DepartmentDto>> CreateDepartmentDto = CreateDepartmentDtoUnexpanded.Expand();
查看更多
登录 后发表回答