這是一個EF Core錯誤還是我做錯了更新一個實體?

.net-core asp.net-core c# entity-framework entity-framework-core

我正在使用Entity Framework Core和存儲庫模式。為了幫助我,我使用基本的CRUD方法編寫了一個基本存儲庫。更新方法如下:

public void Update(TEntity entity)
{
    var contextEntry = _context.Entry<TEntity>(entity);
    if (contextEntry.State == EntityState.Dettached)
    {
        _context.Attach(entity);
    }
    contextEntry.State = EntityState.Modified;
    _context.SaveChanges();
}

鑑於包含此方法的BaseRepository類,我創建了一個繼承BaseRepository User存儲庫

public class UserRepository : BaseRepository<User>, IUserRepository
{
}

我已經在一個用ASP.NET Core編碼的Web API的PUT方法中使用了它

[HttpPut("~/api/users/{id}")]
public IActionResult Put(int id, [FromBody] User user)
{
    if (user == null || user.UserId != id)
    {
        return BadRequest();
    }

    userRepository.Update(user);
    return new NoContentResult();
}

現在,在發出請求時,我在_context.Attach(entity)行中收到一個錯誤。例外情況表明它無法添加實體進行跟踪,因為已經有另一個實體跟踪了相同的密鑰。

調試時,我看到contextEntry.State設置為Unchanged 。因此,它顯然不等於EntityState.Dettached 。仍然,執行進入if語句並嘗試附加實體。

這裡有些不對勁。這是一個錯誤嗎?或者我做錯了什麼?我相信我是這個更新策略非常錯誤的人,但我不確定。在那種情況下,我的方法出了什麼問題?

編輯 :我更新了Update方法只使用_context.Update(entity)_context.SaveChanges() 。仍然, _context.Update(entity)拋出一個帶有此消息的InvalidOperationException

附加信息:無法跟踪實體類型“用戶”的實例,因為已經跟踪了具有相同密鑰的此類型的另一個實例。添加新實體時,對於大多數鍵類型,如果未設置任何鍵,則將創建唯一的臨時鍵值(即,如果為鍵屬性指定了其類型的默認值)。如果要為新實體顯式設置鍵值,請確保它們不會與現有實體或為其他新實體生成的臨時值發生衝突。附加現有實體時,請確保只有一個具有給定鍵值的實體實例附加到上下文。

熱門答案

所有信息都在異常消息中......您已經擁有附加了該主鍵的實體的另一個副本。

我會推薦以下之一(首選首選):

  1. 為每個操作使用新的Context,沒有長期存儲庫/上下文
  2. 使用主鍵在您的上下文中設置.Set<TEntity>.Find(object[] key) ,以便檢索您已有的任何實體。
  3. 在當前的更新方法中,使用Set<TEntity>.Local.Find(..)檢查它是否已存在


Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因