Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework - Duplicate parent(one) when create new child(many)

Because my english is not good, I just straight to the point. Why record Company in database create new record and Customer record refer to new Company record? Thanks for help :)

public class Company : EntityBase
{
    public string Name { get; set; }

    public List<Customer> Customers { get; set; }
    public List<Invoice> Invoices { get; set; }
}

public class Customer : EntityBase
{
    public string Name { get; set; }

    public Company Company { get; set; }
    public List<Card> Cards { get; set; }
}

public class EFRepositoryBase<TEntity> where TEntity : class, IEntity, new()
{
    protected IUnitOfWork UnitOfWork { get; set; }

    protected BenzineFleetContext Context
    {
        get { return (BenzineFleetContext) UnitOfWork; }
    }

    public virtual DbSet<TEntity> GetDbSet<TEntity>() where TEntity : class
    {
        return Context.Set<TEntity>();
    }

    public virtual void Add(TEntity entity)
    {
        GetDbSet<TEntity>().Add(entity);
    }

    public virtual void SaveChanges()
    {
        Context.SaveChanges();
    }
}

    //Save

var cus = new Customer {Company = SelectedCompany}

    _srv.Add(cus);
    _srv.SaveChanges();
like image 529
ypcryz Avatar asked Mar 09 '13 10:03

ypcryz


1 Answers

When you are adding entity via DbSet<T>.Add method, then entity and all it's referenced entities which not in context yet, will be marked as Added in ChangeTracker. That's why new company is added (looks like company is not attached to context):

var customer = new Customer {Company = SelectedCompany}
context.Customers.Add(customer);
// at this point customer state will be Added
// company state also will be Added
context.SaveChanges();

To avoid such behavior, attach company to context before adding new customer:

var customer = new Customer {Company = SelectedCompany}
context.Companies.Attach(SelectedCompany);
context.Customers.Add(customer);
// at this point customer state will be Added
// company state will be Unchanged (if you haven't change it)
context.SaveChanges();

Another way is maintaining states manually:

var customer = new Customer {Company = SelectedCompany}
context.Customers.Add(customer);
context.Entry(SelectedCompany).State = EntityState.Unchanged;
// at this point customer state will be Added
// company state will be Unchanged
context.SaveChanges();
like image 163
Sergey Berezovskiy Avatar answered Sep 21 '22 23:09

Sergey Berezovskiy