實體Famework核心 - 無法跟踪實體類型的實例,因為已經跟踪了具有相同密鑰的此類型的另一個實例

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

我目前正在嘗試使用.net核心和EF核心。

我有以下代碼來更新數據

protected void Update(T entity, bool saveChanges = true)
{
    _context.Set<T>().Attach(entity);
    _context.Entry(entity).State = EntityState.Modified;
    if (saveChanges) _context.SaveChanges();
}

我正在更新的課程

public partial class Blog
{
    public Blog()
    {
        Post = new HashSet<Post>();
    }

    public int BlogId { get; set; }
    public string Url { get; set; }

    public virtual ICollection<Post> Post { get; set; }
}

當我第一次嘗試更新任何條目時,它是成功的。我第二次更新相同的條目,我得到以下錯誤:

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

每個條目都會出現相同的情況,第一次成功,第二次失敗。

附加信息:我使用以下代碼獲取所有數據:

protected IEnumerable<T> GetAll()
{
    return _context.Set<T>().AsNoTracking().AsEnumerable();
}

在視圖中將上面顯示為表格。 DTO用於在數據和Web層之間進行通信。

上下文在啟動時註冊如下

services.AddDbContext<BloggingContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

我的問題是為什麼在第二次更新期間出現錯誤以及如何解決它。謝謝。

一般承認的答案

您的服務提供商是靜態的,因此它實際上是一個單身人士。正如這裡建議的那樣github.com/aspnet/EntityFramework/issues/2652

該異常意味著您嘗試將具有相同鍵的兩個實體實例附加到上下文。在啟動時注入存儲庫的單例實例時會發生這種情況。

我建議將通用存儲庫從抽像類更改為接口,並在啟動期間注入適當的存儲庫:

services.AddScoped<IRepository<Blog>, BlogRepository>();
services.AddScoped<IRepository<Post>, PostRepository>();

而不是靜態的ServiceProvider,它實際上提供了BlogRepository的單例實現



Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow