[英]Entity Framework Core Add entity with dependecy that is saved throws the error
I have something like this entities:我有这样的实体:
class Store
{
public int Id { get; set; }
public List<StoreItem> Items { get; set; }
...
}
class Item
{
public int Id { get; set; }
...
}
class StoreItem
{
public int ItemId { get; set; }
public Item Item { get; set; }
public int StoreId { get; set; }
public Store Store { get; set; }
}
When I added to store saved item and then try to add it to DbSet:当我添加到存储保存的项目然后尝试将其添加到 DbSet 时:
Item item = new Item()
{
...
};
using (var transaction = _dbContext.Database.BeginTransaction())
{
await _dbContext.Items.AddAsync(item); // The item is stored in store StoreItem
await _dbContext.SaveChangesAsync();
}
...
Store store = new Store()
{
...
};
store.Items = new List<StoreItem>()
{
new StoreItem()
{
ItemId = item.Id,
Item = item,
Store = store,
}
};
using (var transaction = _dbContext.Database.BeginTransaction())
{
await _dbContext.Stores.AddAsync(store);
await _dbContext.SaveChangesAsync();
}
this code throws exception that:此代码引发异常:
The instance of entity type 'Item' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.
I cannot get how to add new Store that have dependency on already saved Item ??我无法了解如何添加依赖于已保存项目的新商店?
Issue is reproducible on PostgresSQL, here is project example https://github.com/redradist/SO-ReproducedExample问题可在 PostgresSQL 上重现,这里是项目示例https://github.com/redradist/SO-ReproducedExample
DbSet<T>.Add
will assume that all objects that have not been tracked yet are new. DbSet<T>.Add
将假定尚未跟踪的所有对象都是新对象。
If you want to attach your Item as an existing item, you should do that first, or use context.ChangeTracker.TrackGraph()
so you can specify how each object should be attached.如果您想将您的 Item 作为现有项目附加,您应该首先执行此操作,或者使用context.ChangeTracker.TrackGraph()
以便您可以指定应如何附加每个对象。
Issue was due to that in example https://github.com/redradist/SO-ReproducedExample I used different objects for the same Many-to-Many relationship:问题是由于在示例https://github.com/redradist/SO-ReproducedExample 中,我为相同的多对多关系使用了不同的对象:
var storesForItem1 = new List<StoreItemEntity>()
{
new StoreItemEntity()
{
ItemId = item1Entity.Id,
Item = item1Entity,
Store = storeEntity,
}
};
var storesForItem2 = new List<StoreItemEntity>()
{
new StoreItemEntity()
{
ItemId = item2Entity.Id,
Item = item2Entity,
Store = storeEntity,
}
};
var itemsForStore = new List<StoreItemEntity>()
{
new StoreItemEntity() // <-- Issue, should be used previous created StoreItemEntity for this relationship
{
Item = item1Entity,
StoreId = storeEntity.Id,
Store = storeEntity,
},
new StoreItemEntity() // <-- Issue, should be used previous created StoreItemEntity for this relationship
{
Item = item2Entity,
StoreId = storeEntity.Id,
Store = storeEntity,
}
};
You should use only one entity instance with the same key for particular object对于特定对象,您应该只使用一个具有相同键的实体实例
Here is fixed implementation in branch fixed-example
:这是分支fixed-example
固定实现:
https://github.com/redradist/SO-ReproducedExample/tree/feature/fixed-example https://github.com/redradist/SO-ReproducedExample/tree/feature/fixed-example
- 1 - 1
Most of the time this exception is related with Service Registration
大多数情况下,此异常与Service Registration
And most likely - because you didnt provide more information - your repository/service is registered as a singleton lifetime并且很可能 - 因为您没有提供更多信息 - 您的存储库/服务被注册为单例生命周期
-> Startup.cs
- services.AddSingleton<IRepository, Repository>();
-> Startup.cs
- services.AddSingleton<IRepository, Repository>();
You have to change it to services.AddScoped<IRepository, Repository>();
您必须将其更改为services.AddScoped<IRepository, Repository>();
- 2 - 2
This could be happening because of you are sharing your entity accross multiple DbContext
objects.这可能是因为您正在DbContext
多个DbContext
对象共享您的实体。
Please try to use one context for your method.请尝试为您的方法使用一种上下文。
- 3 - 3
AsNoTracking()
could be helpful, but while you are adding a new entity I don't think that this is the best situation. AsNoTracking()
可能会有所帮助,但是当您添加新实体时,我认为这不是最好的情况。
Among all of the above, I think the source of the problem is what I explained in the 1st point.综上所述,我认为问题的根源是我在第一点中所解释的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.