EF Code First An entity object cannot be referenced by multiple instances of IEntityChangeTracker

c# entity-framework-6 repository-pattern unit-of-work

Question

I have a problem for which lots of answers exist. The exception I've gotten says:

An entity object cannot be referenced by multiple instances of IEntityChangeTracker.

As I've surfed the web and stack over flow pages, I've reached to this point that the instance of the DbContext should be only one in each UnitOfWork or the previous one must be detached. It sounds reasonable! But, my problem is that I have no idea where in my code (posted below) I have to place the modifications. I've been trying to use Generic Repository and Unit of Work pattern plus EF code first approach.

public abstract class Repository<T> : IRepository<T> where T : BaseEntity
{
    protected DbContext EntityContext;
    protected readonly IDbSet<T> DbSet;

    protected Repository(DbContext context)
    {
        EntityContext = context;
        DbSet = context.Set<T>();
    }

    public virtual IEnumerable<T> GetList()
    {
        return DbSet.AsEnumerable();
    }

    public virtual T Add(T entity)
    {
        return DbSet.Add(entity);
    }
}

The generic Unit of Work:

public sealed class UnitOfWork : IUnitOfWork
{
    private DbContext _context;

    public UnitOfWork(DbContext context)
    {
        _context = context;
    }

    public int Commit()
    {
        return _context.SaveChanges();
    }

    private void Dispose(bool disposing)
    {
        if (!disposing) return;
        if (_context == null) return;

        _context.Dispose();
        _context = null;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

The client repository

public class ClientRepository : Repository<Client>, IClientRepository
{
    public ClientRepository(DbContext context)
        : base(context)
    {

    }

    public override Client Add(Client entity)
    {
        return DbSet.Add(entity); // <-- Here the exception comes
    }
}

This is the main part of the 'GenerateClients' method placed inside the 'DataGenerator' project.

var countries = container.Resolve<ICountryService>().GetList().ToList();

        if (!countries.Any())
        {
            throw new InvalidDataGeneratorException(Strings.NoCountryToCreateClient);
        }

        var clientService = container.Resolve<IClientService>();

        clientService.Create(new Client
                             {
                                 Name = "Dell",
                                 CountryId = countries[0].Id,
                                 Country = countries[0],
                                 AddressLineOne = "76-98 Victoria Street",});

And here the ClientService which uses the ClientRepository:

public class ClientService : Service<Client>, IClientService
{
    IUnitOfWork UnitOfWork { get; set; }
    private readonly IClientRepository _clientRepository;
    private readonly ICalculatorService _calculatorService;

    public ClientService(IClientRepository clientRepository,
        IUnitOfWork unitOfWork,
        ICalculatorService calculatorService)
        : base(clientRepository, unitOfWork)
    {
        UnitOfWork = unitOfWork;
        _calculatorService = calculatorService;
        _clientRepository = clientRepository;
    }

    public override void Create(Client client)
    {
        _clientRepository.Add(client);
        _clientRepository.Save();
    }

    }

Please note that some of the methods have been removed in order to minimize the length of the question.

Actually, when I run my Data Generator project which is of type Console, preceding to adding Clients, a number of Countries have been added with no problem, but as it comes to the Client service and it goes down into the ClientRepository, the exception raises up.

I don't know where should I place the modifications to avoid the exception. Many thanks

1
2
7/25/2015 8:08:56 AM

Accepted Answer

does Client have a relation to country and are you adding it as Client.Country = RELATED_COUNTRY perhaps it's trying to add the same country twice, I usually use Client.CountryId = ID_OF_COUNTRY

1
7/25/2015 9:00:16 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow