Reputation: 16290
I have 2 entities:
public class Category
{
public int Id { get; set; }
public string? Name { get; set; }
}
public class Order
{
public int Id { get; set; }
public int CategoryId { get; set; }
public Category Category { get; set; }
}
I load all categories in a list and then create an Order
entity and set its Category
property to one of those in the list. I set the CategoryId
too.
Within the same dbcontext, I save the new order entity using a generic repository pattern:
public virtual T AddOrUpdate(T entity)
{
if (entity.Id == 0)
return Add(entity);
else
{
return Update(entity);
}
}
public virtual T Add(T entity)
{
var dbEntityEntry = context.Entry(entity);
if (dbEntityEntry.State != EntityState.Detached)
dbEntityEntry.State = EntityState.Added;
else
dbSet.Add(entity);
return entity;
}
With the above, I get the following exception:
The instance of entity type 'Category' 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.
Using the context's DebugView
I can see that all Category
items have a state of Unchanged
.
If I set the Category
property to null, the order is inserted correctly.
Is there a better and generic way to save associated entities instead of setting them to null
?
Upvotes: 1
Views: 369
Reputation: 92
When you load the list of categories from the database, it begins tracking them.
When you do order.Category = categories[0]
(or any category of that list), it tries to track that category at position 0 and will try to insert a new category, therefore, just do it like this
order.CategoryId = categories[0].id;
Upvotes: 0