使用 EF 扩展 Select... 以容纳更多字段作为扩展

Extending a Select.... to accommodate more fields as extension using EF

我有一个 class:

public class Employee
{
  public int Id { get; set; }
  public string Name { get; set; }
  public int Salary { get; set; }

  public string Address {get;set;}
}

并且使用 Entity Framework 的查询是:

var selectedEmployee = entities.Employees
                             .Where(e=>e.Salary>10000)
                             .Select(emp => new EmpDTO
                                  {
                                      Id = emp.Id,
                                      Name = emp.Name,
                                      Salary = emp.Salary
                                  });

我的问题是: 我想允许扩展此查询而不重写基本查询。它应该允许通过扩展上述查询在 .Select(.....) 中添加一个新字段。

不重写完整的查询:

var selectedEmployee = entities.Employees
                                 .Where(e=>e.Salary>10000)
                                 .Select(emp => new EmpDTO
                                      {
                                          Id = emp.Id,
                                          Name = emp.Name,
                                          Salary = emp.Salary,

                                          Address = emp.Address

                                      });

我该怎么做?

谢谢

如果我明白了,你可以试试这个:

public IQuerable<EmpDTO> GetEmployee(Func<Employee, EmpDTO> projection = null)
{
    if(projection == null)
        projection = emp => new EmpDTO {
                                  Id = emp.Id,
                                  Name = emp.Name,
                                  Salary = emp.Salary,    
                                };
    return entities.Employees.Where(e => e.Salary > 10000).Select(projection);
}

实施:

var query = classInstance.GetEmployee();
//or
query = classInstance.GetEmployee(emp => new EmpDTO {
                                          Id = emp.Id,
                                          Name = emp.Name,
                                          Salary = emp.Salary,    
                                          Address = emp.Address
                                      });

If you always want to get some set of fields, like Id, Name and Salary and sometimes take additional fields(and specify only their as method arguments), you should to take all fields from DB and only then filter them depends on your condition - it is bad practice to do SELECT *, so you should get default set of fields or specify all desired fields mannualy.

解决方案 SELECT *:

public List<EmpDTO> GetEmployee(Func<Employee, EmpDTO> projection)
{
    var query = entities.Employees.Where(e => e.Salary > 10000).ToList().Select(x => {
         var item = projection == null ? new EmpDTO() : projection(x);
         item.Id = x.Id;
         item.Name = x.Name;
         item.Salary = x.Salary;
         return item;
     }).ToList();
}

At this case return value is List<T> not IQuerable<T>;

实施:

var items = classInstance.GetEmployee(emp => new EmpDTO { Address = emp.Address });
//items also will contain fields: Id, Name and Salary by default