[英]Entity Framework Core is trying to insert duplicated records when SaveChanges() is called
我的實體是:
public class Customer
{
...
public virtual ICollection<ShoppingCartItem> ShoppingCartItems { get; set; }
...
}
public class ShoppingCartItem
{
public string CustomerId { get; set; }
public int ProductId { get; set; }
public virtual Customer { get; set; }
public virtual Product{ get; set; }
...
}
添加方法是:
public async Task AddAsync(TEntity entity)
{
await Task.Factory.StartNew(() => this.entities.Add(entity));
}
我要添加的實體是:
ShoppingCartItem()
{
CustomerId = "xxxxx",
ProductId = 1,
Customer = null,
Product = null
}
當我調用SaveChanges()時,EF試圖為ShoppingCartItem
插入兩個相同的記錄。 ShoppingCartItem
僅創建一次並添加到上下文中。 有什么想法可能是錯誤的嗎?
編輯:
這就是我所謂的AddSync方法:
public async Task AddNewCartItem(ShoppingCartItem shopingCartItem)
{
await this.ShoppingCartItemRepository.AddAsync(shopingCartItem);
await this.SmartStoreWorkData.CompleteAsync();
}
DbContext
不是線程安全的 。 正如注釋中所指出的那樣,毫無意義地-在很可能是其他線程的情況下執行.Add()
,會使DbContext
混亂。 Add()
純粹是一個內存操作; 沒有理由嘗試使其異步。 更改它,我認為它將解決問題。
public void Add(TEntity entity)
{
this.entities.Add(entity);
}
如果您還有其他未在問題中顯示的類似用法,請也將其更改為同步。
您可以使用DbContext
進行“適當的”異步,但僅適用於實際上與數據庫通信的方法,而不適用於內存中的方法,並且通常不涉及Task.<anything>
,而只是提供的async
方法。
編輯 :為完整DbContext
,以上鏈接用於DbContext
,但在EF Core中, DbContext
是線程安全的 。
更新:我做了以下操作:
命令:
dotnet ef --startup-project ../SmartStoreNetCore.Web/ migrations add ChangeShoppingCartItemKey
dotnet ef --startup-project ../SmartStoreNetCore.Web/ database update
在_Layout.cshtml
刪除了以下重復標簽
<script src="~/js/site.js" asp-append-version="true"></script>
site.js
包含用於添加到購物車功能的click事件處理程序
在刪除對
site.js
的重復引用之前, 我可以完全確認 兩次調用以下方法:
public async Task AddNewCartItem(ShoppingCartItem shopingCartItem)
{
await this.ShoppingCartItemRepository.AddAsync(shopingCartItem);
await this.SmartStoreWorkData.CompleteAsync();
}
對我來說,為什么您在調試之前沒有抓住這一點真是太遺憾了
您的配置應如下所示:
builder.Entity<ShoppingCartItem>().HasKey(x => x.Id); // Notice this!
builder.Entity<ShoppingCartItem>().Property(x => x.Id).ValueGeneratedOnAdd(); // Also this!
builder.Entity<ShoppingCartItem>().HasOne(s => s.Customer).WithMany(b => b.ShoppingCartItems).OnDelete(DeleteBehavior.Restrict);
builder.Entity<ShoppingCartItem>().HasOne(s => s.Product).WithMany().OnDelete(DeleteBehavior.Restrict);
自動生成值不會將其定義為主鍵
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.