The instance of entity type 'Customer' cannot be tracked because another instance with the key value '{Id: ...}' is already being tracked

asp.net-mvc c# entity-framework-core

Question

I've already been looking for similar questions but they didn't help me much. It seems to me that my DbContext needs to be Scoped in order to prevent this. Even though I implemented 'AddScoped' previously, it still did not work.

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        // This lambda determines whether user consent for non-essential cookies is needed for a given request.
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });

    services.AddDbContext<ApplicationDbContext>(options =>
    {
        options.EnableSensitiveDataLogging();
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));

    }, ServiceLifetime.Scoped);

    services.AddDefaultIdentity<IdentityUser>()
        .AddDefaultUI(UIFramework.Bootstrap4)
         AddEntityFrameworkStores<ApplicationDbContext>();

    services.Configure<IdentityOptions>(options =>
    {
     ...
    });    
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    services.AddScoped<ISmartyService, SmartyService>();
}

DbContext:

public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
    : base(options)
{
}

public DbSet<Brand> Brand { get; set; }
public DbSet<Car> Car { get; set; }
public DbSet<Customer> Customer { get; set; }
public DbSet<Expense> Expense { get; set; }
public DbSet<Expensetype> Expensetype { get; set; }

Tables

Car

public Guid Id { get; set; }

[ForeignKey("Customer")]
public Guid? Customer_Id { get; set; }

[ForeignKey("Brand")]
public Guid Brand_Id { get; set; }

public string Name { get; set; }

public int Purchase_Price { get; set; }

public int Selling_Price { get; set; }

public int Mileage { get; set; }        

public DateTime InCirculationSince { get; set; }

public DateTime Purchased_At { get; set; }

public DateTime Sold_At { get; set; }

public byte[] Picture { get; set; }

public Customer Customer { get; set; }

public Brand Brand { get; set; }

Customer

public Guid Id { get; set; }

[Required]
public string Firstname { get; set; }

[Required]
public string Lastname { get; set; }

public string Address { get; set; }

[Required]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }

[DataType(DataType.PhoneNumber)]
public string Telephone { get; set; }

Brand

public Guid Id { get; set; }

public string Brandname { get; set; }

The other tables are not necessary atm. I didn't have the chance to work on them. I can't really tell what I'm doing wrong. I believe that the logic I implemented for the upload is correct. It could be that this it the part that I'm doing wrong. for the Upload I'm using the following code:

public void AddOrUpdateCar(Car car)
{
    if (car.Id == Guid.Empty)
    {
        dbContext.Car.Add(car);
    }
    else
    {
        //Where the error occurs
        dbContext.Car.Update(car);
    }

    dbContext.SaveChanges();
}

In Controller:

        Car car = null;

        //Update Condition
        if (viewModel.Id != Guid.Empty)
        {
            car = service.GetCar(viewModel.Id);

            car.Name = service.GetBrandAsString(viewModel.Brand) + " " + viewModel.Name;
            car.Brand_Id = viewModel.Brand;
            car.Purchase_Price = viewModel.Purchase_Price;
            car.Mileage = viewModel.Mileage;
            car.InCirculationSince = viewModel.InCirculationSince;
            car.Purchased_At = viewModel.Purchased_At;

            if (viewModel.Customer != null)
            {
                car.Customer_Id = viewModel.Customer.Id;

                //Applying changes to customer
                car.Customer.Firstname = viewModel.Customer.Firstname;
                car.Customer.Lastname = viewModel.Customer.Lastname;
                car.Customer.Address = viewModel.Customer.Address;
                car.Customer.Email = viewModel.Customer.Email;
                car.Customer.Telephone = viewModel.Customer.Telephone;
            }
        }
        //Add condition
        else
        {
            car = new Car()
            {
                Name = service.GetBrandAsString(viewModel.Brand) + " " + viewModel.Name,
                Brand_Id = viewModel.Brand,
                Purchase_Price = viewModel.Purchase_Price,
                Mileage = viewModel.Mileage,
                InCirculationSince = viewModel.InCirculationSince,
                Purchased_At = viewModel.Purchased_At                  
            };
        }

        if (viewModel.Picture != null)
        {
            car.Picture = ResizeImage(viewModel.Picture, 285, 144);
        }

        service.AddOrUpdateCar(car);

Full error message

System.InvalidOperationException: 'The instance of entity type 'Customer' cannot be tracked because another instance with the key value '{Id: 626c03d3-4d66-44db-acad-1342dd9bc4ae}' is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.'

Any help will be appreciated! Any help that makes this problem less excruciating

1
1
8/24/2019 10:07:29 AM

Popular Answer

After a lot of trying, I was finally able to solve the problem. Even though I previously updated the customer like this:

car.Customer = viewModel.Customer;

It didn't apply the changes. I believe that EF Core thought that nothing has changed and that I'm trying to add a new item with the same Id. So after telling EF Core that the customer has changed by applying the changes, it worked perfectly.

I changed the code in my question in order to explain my answer. I had to change the code in the controller.

0
8/24/2019 10:13:44 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