Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将linq中的select子句组合到具有匿名类型的实体_C#_.net_Linq To Entities_Expression Trees_Anonymous Types - Fatal编程技术网

C# 将linq中的select子句组合到具有匿名类型的实体

C# 将linq中的select子句组合到具有匿名类型的实体,c#,.net,linq-to-entities,expression-trees,anonymous-types,C#,.net,Linq To Entities,Expression Trees,Anonymous Types,如何将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 Add

如何将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
});
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
});
我还需要请求与我的Employee类相同的属性以及特定属性:

Context.Persons.Where(...).Select(p => new 
{
    p.Name,
    PersonCity = p.Address.City,
    //other needed properties
});
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
});
Context.Employees.OfType()。其中(…)。选择(e=>new
{
e、 薪水,
ManagerName=e.Manager.Name,
e、 名字,
PersonCity=e.City.Name,
//其他所需属性与上一个“使用人员选择”实体相同
});
使用表达式树操作(或其他解决方案)是否可以组合两个select子句,以避免从my 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"
// }
var personSelect=p=>new{
p、 名字,
PersonCity=p.Address.City,
//其他所需财产
};
var employeeSelect=personSelect.Combine(e=>new{
e、 薪水,
ManagerName=e.Manager.Name
});
context.Employees.OfType().Where(…).Select(employeeSelect).FirstOrDefault();
//返回一个匿名对象
// {
//Name=“Joachim”,
//PersonCity=“里昂”,
//     
//工资=65432.10,
//ManagerName=“塞缪尔”
// }

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

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

  • Employee
    的匿名类型将有一个名为
    PersonData
    的属性,该属性将包含包含来自
    Person
    的信息的匿名类型
  • 您可以创建正常类型,如
    PersonData
    EmployeeData
    (继承自
    PersonData
    )。每种类型都可以给您一个表达式来创建它,而
    EmployeeData
    的表达式将基于
    PersonData
    的表达式进行计算

  • 在这两种情况下,您都需要一些表达式树,但要做到这一点并不难。

    您基本上想要
    表达式组合的实现吗(表达式e1,ExpressionOh等等,它不会工作。我明白svick的意思了。在
    employeeSelect
    的lambda中创建的匿名类型不够全面,函数无法返回新的匿名类型。函数必须具有签名
    表达式组合(表达式e1,表达式)其中TInput2:TInput1
    TOutput3
    在编译时不存在。好的,我明白了,谢谢@Sholmo和svick的帮助和解释。