Search code examples
c#linqinsert-updategeneric-listupsert

Is there a way to update a generic list using LINQ rather than deleting a member of the list and adding it back?


Does LINQ allow an Upsert type of operation, or for updating an existing record? I have the following code that grabs a "record" from the list, updates certain parts of it, then deletes the original one and adds back this updated one:

. . .
Student student = LINQ2ObjectsCode.GetStudentForId(ah.StudentID_FK);
// Update several members of the Students list...
student.WeekOfLastAssignment = _currentWeek;
int nextTalkTypeId = AYttFMConstsAndUtils.GetNextTalkIDForBrothers(ah.StudentID_FK, 1); 
student.RecommendedNextTalkTypeID = nextTalkTypeId;
student.NextCounselPoint = LINQ2ObjectsCode.GetNextCounselPoint(nextTalkTypeId, student.NextCounselPoint);
// ...then update that record by first deleting the old one...
AYttFMConstsAndUtils.StudentsList.RemoveAll(x => x.StudentID == ah.StudentID_FK);
// ...and then adding back the updated one:
AYttFMConstsAndUtils.StudentsList.Add(student);
. . .

public static Student GetStudentForId(int _studentId)
{
    return AYttFMConstsAndUtils.StudentsList.SingleOrDefault(
        i => i.StudentID.Equals(_studentId));
}

...but I don't know if that is the preferred approach. Is there a way to Update the existing record, rather than destroy it and replace it with the new version? I imagine there is, but I don't know how convoluted, and whether it's really better or just different. I'm going to have several similar methods, but I don't want to do the "wrong" thing multiple times.

Note: The data does not come from a database; rather, it is stored in json files.


Solution

  • You don't need to delete and add the entity again.

    In general, if the list is a local list, the objects are by reference. So you can query an object, and modify its properties in place, and you have updated the fields of the real object.

    And for LINQ2SQL or EF or ORM entities, whenever you fetch a record, the Context managers keep track of the state of the entity. You can modify its properties, and do a SubmitChanges() or SaveChanges() on the context, and the record will be updated automatically.

    Note that you need to be in the scope of the context to do a fetch, modify some properties and do a save changes. If you have lost the context after fetching the entity, you can still easily modify the entity, just that you need to attach the object again and save the context.

    let me know if you need LINQ2SQL or EF instances of doing this. (attaching entities)

    e.g.

    using (var context = new YourDbContext())
    {
     Student student = LINQ2ObjectsCode.GetStudentForId(context, ah.StudentID_FK);
     // Update several members of the Students list...
     student.WeekOfLastAssignment = _currentWeek;
     int nextTalkTypeId =  
     AYttFMConstsAndUtils.GetNextTalkIDForBrothers(ah.StudentID_FK, 1); 
     student.RecommendedNextTalkTypeID = nextTalkTypeId;
     student.NextCounselPoint = LINQ2ObjectsCode.GetNextCounselPoint(nextTalkTypeId,  
     student.NextCounselPoint);
    
     context.SaveChanges(); // ef
    }