Ivan-Mark Debono
Ivan-Mark Debono

Reputation: 16290

How to save an entity with associated entities?

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

Answers (1)

Michael
Michael

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

Related Questions