【发布时间】:2010-11-10 21:11:47
【问题描述】:
以下 sn-p 确实可以满足我的需要。我相信虽然必须有更好的做法?执行此查询的更优化方法?
需要的是获得一个员工对象列表,这些对象是员工/经理 x 的直接下属。直接下属列在历史表中,每个员工都有多条记录,因此每个直接下属(员工)应该从该表返回一条(最近的)记录,然后应该使用 Employee 表来获取员工 id 等于此过滤结果集中每个历史记录中的员工 id 的员工对象。我可以使用两个单独的 LINQ to EF 查询来获得两半。
尝试从第一个结果集中加入employeeHistory 对象时出现问题。根据 MSDN:不支持引用非标量闭包 [不支持在查询中引用非标量闭包,例如实体。执行此类查询时,会引发 NotSupportedException 异常,并显示一条消息,指出“无法创建‘闭包类型’类型的常量值。在此上下文中仅支持原始类型(‘例如 Int32、String 和 Guid’) ."]
所以我运行了两个查询,第一个是 int 类型的列表,而不是一个复杂的对象。这确实有效,但似乎是做作的。关于更好方法的任何建议(我想做一个查询)。
private List<BO.Employee> ListDirectReports(int mgrId)
{
IQueryable<BO.Employee> directRpts;
using(var ctx = new Entities())
{
//to get a list of direct rpts we perform two separate queries. linq to ef with linq to objects
//first one gets a list of emp ids for a direct mgr emp id from the history table
//this first qry uses grouping and a filter by empid and a filter by max(date)
//the second qry joins to the resultset from the first and goes to the employee table
//to get whole employee objects for everyone in the int emp id list from qry #1
//qry #1: just a list of integers (emp ids for those reporting to emp id of mgrId)
IEnumerable<int> directRptIDList =
from employeeHistory in ctx.EmployeeHistory
.Where(h => h.DirectManagerEmployeeID == mgrId).ToList()
group employeeHistory by employeeHistory.EmployeeID into grp
let maxDt = grp.Max(g => g.DateLastUpdated) from history in grp
where history.DateLastUpdated == maxDt
select history.EmployeeID;
//qry #2: a list of Employee objects from the Employee entity. filtered by results from qry #1:
directRpts = from emp in ctx.Employee
join directRptHist in directRptIDList.ToList()
on emp.EmployeeID equals directRptHist
select emp;
}
return directRpts.ToList();
}
谢谢。
【问题讨论】:
标签: c# linq entity-framework