简体   繁体   中英

Get Last Record from Multiple Records and save result in LINQ List

I have a table 'Status Which has multiple status of User . I just want to read the last . I just want to read the last Status of every user`. How could I achive that in Lambda Linq to SQL.

-------Status-------------
|   user1, Stats_Active   |
|   user1, Stats_InActive |
|   user1, Stats_Deleted  |
|   user2, Stats_Login    |
|   user2, Stats_Logout   |
|   user2, Stats_Edited   |
________________________

I want to get the following output:

User1, Status_Delete
User2,Status_edited

This is my Linq to SQL Query:

EntityName db = new EntityName();
var result = db.Status.OrderByDescending(k=> k.DateTime).List()

This just returns the whole list in Descending order. How can I achieve my desired output?

I think that you need something like this:

var result = db.Status
               .AsEnumerable()
               .GroupBy(s=>s.UserId)
               .Select(gr=>
               {
                   // Generally you should avoid use the First
                   // and you should use the FirstOrDefault
                   // but in this context is safe to use First.
                   var mostRecentComplaint = gr.OrderByDescending(k=> k.DateTime)
                                               .First();
                   return new Complaint_DTO
                   {
                       ComplaintId = gr.Key,
                       Status = mostRecentComplaint.Status,
                       CreatedDate = mostRecentComplaint.CreatedDate
                   };
               }).ToList(); 
  • First we group by our items by the UserId. So all the records that have the same UserId goes to the same group.
  • Then Ordering the result of each group by descending DateTime and getting the first item of each of these groups, we get the expected result.

You need to group by UserId and then order your groups by DateTime property:

var result =(from s in db.Status
             group s by s.UserId into g
             let first=g.OrderByDescending(s=>s.DateTime).FirstOrDefault()
             select new { userId= g.Key, Status= first.Status, CreatedDate=first.CreatedDate}).ToList();

Update

I tested my query using LinqPad , and it was translated to this lambda expression:

Status
   .GroupBy (a => a.UserId)
   .Select (
      g => 
         new  
         {
            g = g, 
            first = g.OrderBy (a => a.DateTime).FirstOrDefault ()
         }
   )
   .Select (
      temp0 => 
         new  
         {
            Key = temp0.g.Key, 
            Status= temp0.first.Status,
            CreatedDate=temp0.first.CreatedDate
         }
   )

Which is translated at the end to this SQL query:

SELECT [t1].[UserId] AS [UserId], (
    SELECT [t3].[Status], [t3].[DateTime]
    FROM (
        SELECT TOP (1) [t2].[Status]
        FROM [Status] AS [t2]
        WHERE (([t1].[UserId] IS NULL) AND ([t2].[UserId] IS NULL)) OR (([t1].[UserId] IS NOT NULL) AND ([t2].[UserId] IS NOT NULL) AND ([t1].[UserId] = [t2].[UserId]))
        ORDER BY [t2].[DateTime]
        ) AS [t3]
    ) AS [Status],(
    SELECT [t5].[DateTime]
    FROM (
      SELECT TOP (1) [t4].[DateTime]
      FROM [Application] AS [t4]
      WHERE (([t1].[UserId] IS NULL) AND ([t4].[UserId] IS NULL)) OR (([t1].[UserId] IS NOT NULL) AND ([t4].[UserId] IS NOT NULL) AND ([t1].[UserId] = [t4].[UserId]))
      ORDER BY [t4].[DateTime]
      ) AS [t5]
    ) AS [DateTime]
FROM (
    SELECT [t0].[UserId]
    FROM [Application] AS [t0]
    GROUP BY [t0].[UserId]
    ) AS [t1]

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