我已经在寻找类似的问题,但是它们并没有太大帮助。在我看来,我的DbContext需要进行范围调整以防止这种情况。即使我以前实现了“ AddScoped”,它仍然无法正常工作。
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; }
表格
汽车
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; }
客户
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; }
品牌
public Guid Id { get; set; }
public string Brandname { get; set; }
其他表不是必需的atm。我没有机会研究它们。我真的不能说我在做什么错。我认为我为上传实现的逻辑是正确的。可能这就是我做错的部分。对于上传,我正在使用以下代码:
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();
}
在控制器中:
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);
完整的错误消息
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.'
任何帮助将不胜感激!任何有助于减轻此问题困扰的帮助
答案 0 :(得分:0)
在您的控制器代码中,您正在创建Car
实体的新实例以对其进行更新(我假设...是因为您使用viewModel.Id
作为ID)。 / p>
因为您正在创建此实例,而不是从上下文中检索它,所以上下文不会对其进行跟踪,并且在尝试更新时会收到此错误,因为新创建的{{ 1}}实例与上下文已经跟踪的实例匹配。
为了更新现有实体,您需要首先从上下文中检索它,然后根据需要更改其属性,然后Id
对其进行编辑...
Car
答案 1 :(得分:0)
经过大量的尝试,我终于能够解决问题。即使我以前是这样更新客户的:
car.Customer = viewModel.Customer;
它没有应用更改。我相信EF Core认为一切都没有改变,并且我正在尝试添加具有相同ID的新项目。因此,在告知EF Core客户已通过应用更改进行了更改之后,它可以正常工作。
我更改了问题代码以解释我的答案。我不得不更改控制器中的代码。