我的实体是:
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; }
...
}
add方法是:
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();
}
答案 0 :(得分:3)
DbContext
是 not thread safe 。毫无意义地,正如评论中所述 - 在很可能是不同的主题中执行您的.Add()
时,您会混淆DbContext
。 Add()
纯粹是一种记忆中的操作;没有理由试图让它异步。改变这一点,我认为它将解决问题。
public void Add(TEntity entity)
{
this.entities.Add(entity);
}
如果您的问题中未显示任何其他类似用法,请将其更改为同步。
你可以做&#34;正确&#34;与DbContext
异步,但它仅适用于实际与数据库通信的方法,而不是内存中的方法,并且通常不涉及Task.<anything>
,只提供async
方法。< / p>
修改:为了完整性,上面的链接适用于EF6,但在EF Core中,DbContext
也是not thread-safe。
答案 1 :(得分:1)
更新:我做了以下事情:
命令:
I2
在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
的重复引用:
site.js
对我来说,为什么在通过调试
之前没有意识到这一点,这是一种谜您的配置应如下所示:
public async Task AddNewCartItem(ShoppingCartItem shopingCartItem)
{
await this.ShoppingCartItemRepository.AddAsync(shopingCartItem);
await this.SmartStoreWorkData.CompleteAsync();
}
自动生成值不会将其定义为主键