簡體   English   中英

實體框架更新相關實體,而沒有並發沖突

[英]Entity framework update related entities without concurrency conflict

我有兩個相關的實體:User和UserProfile。 用戶可以具有許多配置文件(設置)。 我希望能夠一起更新它們,但是這樣做時當前出現並發錯誤:

存儲更新,插入或刪除語句影響了意外的行數(0)。 自加載實體以來,實體可能已被修改或刪除。 有關了解和處理樂觀並發異常的信息,請參見http://go.microsoft.com/fwlink/?LinkId=472540

這是我要更新的代碼:

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();
    }
}

當我添加兩個實體時,它工作得很好,但在更新時卻不能。 有任何想法嗎?

我發現自己在使用其他上下文來獲取要更新的配置文件。 這導致並發沖突,因為EF認為此實體已在其他地方(另一個上下文)更改。 因此,我為此方法創建了一個重載,以便可以將上下文作為參數傳遞,並使用與更新它時相同的上下文來獲取實體。

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();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM