简体   繁体   中英

LINQ returning records with most recent dates with a join

I am trying create a LINQ statement that returns a list of records (tasks) with their most recent assigned task history date. So there are two tables the first is the task table which contains all of the information about a single task and then there is the task history table which keeps track of how and to who the task gets assigned to. Both of these tables have TaskID which is where they can be linked on a join. The issue is that in the task history there can be many records with the same TaskID but I only want to return the record with most recent assigned date which is a column in the task history table. How can I do this?

Here is what I have so far:

var query = from task in db.AP_Tasks
            join taskH in db.AP_TaskHistory on task.TaskID equals taskH.TaskID
            orderby new {taskH.AssignDate}
            select new {task = task, assignedDate = taskH.AssignDate};

Update:

Most Recent Code:

        var query = from task in db.AP_Tasks
            from th in db.AP_TaskHistory
            where th.TaskID == task.TaskID
            orderby th.AssignDate
            select new {task = task, assignDate = th.AssignDate};

What you need here is a CROSS APPLY style query.

select AP_Tasks.*, history.AssignDate
from AP_Tasks
cross apply (
   select top 1 AP_TaskHistory.AssignDate
   from AP_TaskHistory
   where AP_Tasks.TaskID = AP_TaskHistory.TaskID
   order by AP_TaskHistory.AssignDate DESC
) history

See here: How do I write this cross apply query in LINQ-to-SQL?

I think something like this would work for you.

var query = (from task in db.AP_Tasks
            join taskH in db.AP_TaskHistory on task.TaskID equals taskH.TaskID
            orderby new {taskH.AssignDate} descending
            select new {task = task, assignedDate = taskH.AssignDate}).First();

Be warned, I haven't tested this.

Instead of .First() you could try .FirstOrDefault() in order to more easily handle exceptions.

Here is an example to get you going:

List<Task> tasks = new List<Task>();
tasks.Add(new Task {TaskID = 1});
tasks.Add(new Task {TaskID = 3});
tasks.Add(new Task {TaskID = 5});

List<TaskHistory> taskHistories = new List<TaskHistory>();
taskHistories.Add(new TaskHistory { TaskID = 3, AssignDate = DateTime.Now });
taskHistories.Add(new TaskHistory { TaskID = 3, AssignDate = DateTime.Now.AddDays(3) });
taskHistories.Add(new TaskHistory { TaskID = 1, AssignDate = DateTime.Now });
taskHistories.Add(new TaskHistory { TaskID = 1, AssignDate = DateTime.Now.AddDays(1) });
taskHistories.Add(new TaskHistory { TaskID = 1, AssignDate = DateTime.Now.AddDays(4) });

var query = from task in tasks
            join thist in taskHistories on task.TaskID equals thist.TaskID
            group new { t = task, date = thist.AssignDate } by task.TaskID into grouped
            from g in grouped
            where g.date == grouped.Max(taskInGroup => taskInGroup.date)
            select g;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM