簡體   English   中英

實體框架核心正在嘗試在調用SaveChanges()時插入重復的記錄

[英]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線程安全的

更新:我做了以下操作:

  • 克隆了您的回購鏈接: SmartStoreNETCore
  • 使用新的EF工具遷移到.NET Core 1.1(preview4)
  • 添加了下面的EF ModelBuilder中指定的配置
  • 應用遷移和更新數據庫

命令:

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

對我來說,為什么您在調試之前沒有抓住這一點真是太遺憾了

EF ModelBuilder

您的配置應如下所示:

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.

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