Note that there are some explanatory texts on larger screens.

plurals
  1. POFiltering by max and grouping by id with joins to other entities in LINQ to Entity Framework (C#)
    primarykey
    data
    text
    <p>The following snippet does work for what I need. I believe though that there must be a better practice? A more optimal way of doing this query? </p> <p>What is needed is to get a list of employee objects that are the direct reports for employee/mgr x. The direct reports are listed in a history table that has multiple records for each employee, and so only one (the most recent) record should be returned from that table per each direct report (employee) and then the Employee table should be used to get the employee object where employee id is equal to employee id from each history record in this filtered resultset. I can get both halves with two separate LINQ to EF queries. </p> <p>A problem occurs when trying to join on the employeeHistory object from the first result set. According to MSDN: Referencing Non-Scalar Closures is Not Supported [Referencing a non-scalar closure, such as an entity, in a query is not supported. When such a query executes, a NotSupportedException exception is thrown with a message that states "Unable to create a constant value of type 'Closure type'. Only primitive types ('such as Int32, String, and Guid') are supported in this context."]</p> <p>So I run two queries and make the first a list of type int rather than a complex object. This does work, but seems contrived. Any suggestions as to a better way (I would like to do one query).</p> <pre><code>private List&lt;BO.Employee&gt; ListDirectReports(int mgrId) { IQueryable&lt;BO.Employee&gt; 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&lt;int&gt; directRptIDList = from employeeHistory in ctx.EmployeeHistory .Where(h =&gt; h.DirectManagerEmployeeID == mgrId).ToList() group employeeHistory by employeeHistory.EmployeeID into grp let maxDt = grp.Max(g =&gt; 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(); } </code></pre> <p>Thank you.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload