0

I have two related entities: User and UserProfile. A user can have many profiles (settings). I want to be able to update them together, but I am currently getting concurrency error when i do so:

Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=472540 for information on understanding and handling optimistic concurrency exceptions.

This is my code to update:

public void UpdateUser(UserList user, int timeoutMins)
{
    using (var ctx = GetCodingContext())
    {
        try
        {
            ctx.Entry(user).State = System.Data.Entity.EntityState.Modified;
            CR_USER_PROFILE timeoutProfile = GetTimeoutUserProfile(user.UserGUID);
            if (timeoutProfile != null && !timeoutProfile.PROFILE_VALUE.Equals(timeoutMins.ToString()))
            {
                timeoutProfile.PROFILE_VALUE = timeoutMins.ToString();
                UpdateUserProfile(timeoutProfile,ctx);
            }
            else if(timeoutProfile == null && timeoutMins > 0)
            {
                var timeoutKey = FFCEnumerations.Profiles.Keys.Timeout.GetStringValue();
                AddUserProfile(user, timeoutKey, timeoutMins.ToString(), ctx);
            }
            ctx.SaveChanges();
        }
        catch (Exception ex)
        {
            throw new Exception("Error occurred updating user " + ex);
        }
    }
}

public void UpdateUserProfile(CR_USER_PROFILE profile, CodingContext ctx)
{
    try
    {
        ctx.Entry(profile).State = System.Data.Entity.EntityState.Modified;
    }
    catch (Exception)
    {
        throw new Exception("Error occurred updating User Profile");
    }
}

public CR_USER_PROFILE GetTimeoutUserProfile(Guid userGuid)
{
    using (var ctx = GetCodingContext())
    {
        var timeoutKey = FFCEnumerations.Profiles.Keys.Timeout.GetStringValue();
        var profileList = ctx.CR_USER_PROFILE.Where(p => p.UserGUID == userGuid && p.PROFILE_TYPE_CD == timeoutKey);
        return profileList.SingleOrDefault();
    }
}

It works well when I add both entities, but not when updating. Any ideas?

roca323
  • 455
  • 2
  • 8
  • 26

2 Answers2

0

I think this is where there's a lot of discussion on this problem - Entity Framework: "Store update, insert, or delete statement affected an unexpected number of rows (0)."

Batgirl
  • 106
  • 7
0

I figured out that I was using a different context for fetching the profile I wanted to update. This was causing the concurrency conflict because EF thought this entity was being changed somewhere else (another context). So, I created an overload for this method so I can pass the context as an argument and fetch the entity with the same context I was going to update it with.

public CR_USER_PROFILE GetTimeoutUserProfile(Guid userGuid, CodingContext ctx)
{
    var timeoutKey = FFCEnumerations.Profiles.Keys.Timeout.GetStringValue();
    var profileList = ctx.CR_USER_PROFILE.Where(p => p.UserGUID == userGuid && p.PROFILE_TYPE_CD == timeoutKey);
    return profileList.SingleOrDefault();
}
roca323
  • 455
  • 2
  • 8
  • 26