Kombinieren Sie SELECT-Klauseln in linq mit Entitäten mit anonymen Typen

.net anonymous-types c# expression-trees linq-to-entities

Frage

Wie kann ich Select-Klausel in Linq mit Entitäten kombinieren, um in einen anonymen Typ zu projizieren?
Angenommen, ich habe diese Entitäten:

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

Manchmal muss ich nur wenige Eigenschaften meiner Person-Klasse anfordern:

Context.Persons.Where(...).Select(p => new 
{
    p.Name,
    PersonCity = p.Address.City,
    //other needed properties
});

Und ich muss auch die gleichen Eigenschaften meiner Employee-Klasse sowie die spezifischen Eigenschaften anfordern:

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

Ist es mit Ausdruckbaummanipulationen ( oder einer anderen Lösung ) möglich, zwei select-Klauseln zu kombinieren, um nicht die gesamte select-Klausel aus meiner Person-Entität zu duplizieren?

So ähnlich:

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"
// }

Akzeptierte Antwort

Nein, es gibt keine Möglichkeit genau das zu tun, wonach du verlangst. Das Problem besteht darin, dass jeder anonyme Typ zum Zeitpunkt der Kompilierung erstellt werden muss, die Ausdrucksbäume jedoch zur Laufzeit funktionieren.

Ich kann zwei Möglichkeiten sehen, um das zu umgehen:

  1. Ihr anonymer Typ für Employee hätte eine Eigenschaft namens PersonData , die den anonymen Typ mit den Informationen von Person .
  2. Sie würden normale Typen wie PersonData und EmployeeData (die von PersonData erbt) PersonData . Jeder Typ könnte Ihnen einen Ausdruck zum Erstellen geben und der Ausdruck von EmployeeData würde basierend auf dem Ausdruck von PersonData berechnet werden.

In beiden Fällen würden Sie einige Ausdruckbäume benötigen, aber das sollte nicht schwer sein.



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow