score:2

You could create a dictionary for the version comments and use it to simplify the population of the output's Comments property.

The suggestion below is based on the assumption that for each Version's collection of records associated with the target UserId, there is:

  • exactly one record for a change in the "Comments" column
  • at least one record for a change in any other column

I have marked all changes made to the original code with comments.

var query = context.UserChangeLogs
    .Where(u => u.UserId == 100)
    .OrderByDescending(p => p.Version); //latest version data first
    .ToList();

// ADDED
const string CommentsColumn = "Comments";

// ADDED
// Dictionary associating the version comment with the ID of the first record for the version
var commentForRecordWithId = query
    .GroupBy(entry => entry.Version)
    .ToDictionary(
        gr => gr.First(entry => entry.Column != CommentsColumn).Id, 
        gr => gr.First(entry => entry.Column == CommentsColumn).UpdatedValue);

var output = query
    .Where(a => a.Column != CommentsColumn) // ADDED - we don't want the Comments column change records in output
    .Select(a => new UserChangeLogsPOCO
    {
        Id = a.Id,
        Version = a.Version,
        Column = a.Column,
        OriginalValue = a.OriginalValue,
        UpdatedValue = a.UpdatedValue,
        // CHANGED:
        Comments = commentForRecordWithId.ContainsKey(a.Id)
            ? commentForRecordWithId[a.Id]
            : null
    }).ToList();

EDIT: The code above also assumes that the context.UserChangeLogs is in chronological order, i.e. ordered by Id, at the time the query variable is assigned.


Related Articles