C# 实体框架核心在更新期间删除实体
我有一个关于ASP.NET核心中实体的问题。 我使用实体框架核心作为数据访问库。 我遇到的问题发生在我尝试更新实体时。在我修改属性并调用SaveChanges之后,实体被删除,我不明白为什么。 以下是实体:C# 实体框架核心在更新期间删除实体,c#,entity-framework-core,C#,Entity Framework Core,我有一个关于ASP.NET核心中实体的问题。 我使用实体框架核心作为数据访问库。 我遇到的问题发生在我尝试更新实体时。在我修改属性并调用SaveChanges之后,实体被删除,我不明白为什么。 以下是实体: public class Contract { public int Id { get; set; } [Required] public DateTime ExpiryDate { get; set; } [Requi
public class Contract
{
public int Id { get; set; }
[Required]
public DateTime ExpiryDate { get; set; }
[Required]
[Range(0, float.MaxValue)]
public float MonthlyFee { get; set; }
[Required]
public string UserId { get; set; }
[Required]
public int CarId { get; set; }
public User User { get; set; }
public Car Car { get; set; }
}
以下是相关实体供参考:
public class User : IdentityUser
{
[Required]
[PersonalData]
public string Name { get; set; }
[Required]
[PersonalData]
public string Surname { get; set; }
[Required]
[PersonalData]
public string TaxCode { get; set; }
[Required]
[PersonalData]
[DataType(DataType.Date)]
public DateTime DateOfBirth { get; set; }
public string ProfilePictureUrl { get; set; }
public Contract Contract { get; set; }
public ICollection<CarAccident> CarAccidents { get; set; }
}
public class Car
{
public int Id { get; set; }
[Required]
[RegularExpression("[A-Z][A-Z][0-9][0-9][0-9][A-Z][A-Z]")]
public string LicensePlate { get; set; }
public int CarModelId { get; set; }
public string FittingDescription { get; set; }
public Contract Contract { get; set; }
public ICollection<CarAccident> CarAccidents { get; set; }
public CarModel CarModel { get; set; }
}
公共类用户:IdentityUser
{
[必需]
[个人资料]
公共字符串名称{get;set;}
[必需]
[个人资料]
公共字符串姓氏{get;set;}
[必需]
[个人资料]
公共字符串TaxCode{get;set;}
[必需]
[个人资料]
[数据类型(DataType.Date)]
公共日期时间出生日期{get;set;}
公共字符串ProfilePictureUrl{get;set;}
公共合同{get;set;}
公共ICollection CarAccidents{get;set;}
}
公车
{
公共int Id{get;set;}
[必需]
[常规表达(“[A-Z][A-Z][0-9][0-9][0-9][A-Z][A-Z]”)
公共字符串许可证牌{get;set;}
公共int CarModelId{get;set;}
公共字符串FittingDescription{get;set;}
公共合同{get;set;}
公共ICollection CarAccidents{get;set;}
公共CarModel CarModel{get;set;}
}
以下是我在存储库中的更新方法:
public async Task<Contract> Update(Contract entity)
{
var dbContract = await GetById(entity.Id);
if (dbContract == null)
return null;
var dbUser = await _userRepository.GetById(entity.UserId);
if (dbUser == null)
return null;
var dbCar = await _carRepository.GetById(entity.CarId);
if (dbCar == null)
return null;
dbContract.ExpiryDate = entity.ExpiryDate;
dbContract.User = entity.User;
dbContract.Car = dbCar;
dbContract.User = dbUser;
//_context.Contracts.FromSqlInterpolated($"UPDATE dbo.Contracts SET ExpiryDate={entity.ExpiryDate}, MonthlyFee={entity.MonthlyFee} WHERE Id={entity.Id}");
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateException)
{
return null;
}
return await GetById(entity.Id);
}
public async Task<Contract> Update(Contract entity)
{
var dbContract = await _context.Contracts.Include(c => c.User).Include(c => c.Car).FirstOrDefaultAsync(c => c.Id == entity.Id);
if (dbContract == null)
{
throw new EntityNotFoundException();
}
var dbUser = await _context.Users.Include(u => u.Contract).FirstOrDefaultAsync(u => u.Id == entity.UserId);
if (dbUser == null)
return null;
var dbCar = await _context.Cars.Include(c => c.Contract).FirstOrDefaultAsync(c => c.Id == entity.CarId);
if (dbCar == null)
return null;
dbContract.ExpiryDate = entity.ExpiryDate;
dbContract.MonthlyFee = entity.MonthlyFee;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateException)
{
return null;
}
return await GetById(entity.Id);
}
公共异步任务更新(合同实体)
{
var dbContract=await GetById(entity.Id);
if(dbContract==null)
返回null;
var dbUser=await_userRepository.GetById(entity.UserId);
if(dbUser==null)
返回null;
var dbCar=await_carRepository.GetById(entity.CarId);
if(dbCar==null)
返回null;
dbContract.ExpiryDate=entity.ExpiryDate;
dbContract.User=entity.User;
dbContract.Car=dbCar;
dbContract.User=dbUser;
//_context.Contracts.FromSqlInterpolated($“UPDATE dbo.Contracts SET ExpiryDate={entity.ExpiryDate},MonthlyFee={entity.MonthlyFee},其中Id={entity.Id}”);
尝试
{
wait_context.SaveChangesAsync();
}
捕获(DbUpdateException)
{
返回null;
}
返回等待GetById(entity.Id);
}
有人知道怎么解决这个问题吗
更新:
这是新的更新方法:
public async Task<Contract> Update(Contract entity)
{
var dbContract = await GetById(entity.Id);
if (dbContract == null)
return null;
var dbUser = await _userRepository.GetById(entity.UserId);
if (dbUser == null)
return null;
var dbCar = await _carRepository.GetById(entity.CarId);
if (dbCar == null)
return null;
dbContract.ExpiryDate = entity.ExpiryDate;
dbContract.Car = dbCar;
dbContract.User = dbUser;
//_context.Contracts.FromSqlInterpolated($"UPDATE dbo.Contracts SET ExpiryDate={entity.ExpiryDate}, MonthlyFee={entity.MonthlyFee} WHERE Id={entity.Id}");
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateException)
{
return null;
}
return await GetById(entity.Id);
}
公共异步任务更新(合同实体)
{
var dbContract=await GetById(entity.Id);
if(dbContract==null)
返回null;
var dbUser=await_userRepository.GetById(entity.UserId);
if(dbUser==null)
返回null;
var dbCar=await_carRepository.GetById(entity.CarId);
if(dbCar==null)
返回null;
dbContract.ExpiryDate=entity.ExpiryDate;
dbContract.Car=dbCar;
dbContract.User=dbUser;
//_context.Contracts.FromSqlInterpolated($“UPDATE dbo.Contracts SET ExpiryDate={entity.ExpiryDate},MonthlyFee={entity.MonthlyFee},其中Id={entity.Id}”);
尝试
{
wait_context.SaveChangesAsync();
}
捕获(DbUpdateException)
{
返回null;
}
返回等待GetById(entity.Id);
}
以下是Fluent API配置:
private void _configureUsers(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>()
.HasOne(u => u.Contract)
.WithOne(c => c.User)
.HasForeignKey<Contract>(c => c.UserId);
}
private void _configureCars(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Car>()
.HasAlternateKey(c => c.LicensePlate);
modelBuilder.Entity<Car>()
.HasOne(c => c.Contract)
.WithOne(c => c.Car)
.HasForeignKey<Contract>(c => c.CarId);
}
private void\u配置用户(ModelBuilder ModelBuilder)
{
modelBuilder.Entity()
.HasOne(u=>u.Contract)
.WithOne(c=>c.User)
.HasForeignKey(c=>c.UserId);
}
专用void\u配置车辆(ModelBuilder ModelBuilder)
{
modelBuilder.Entity()
.HasaAlternateKey(c=>c.LicensePlate);
modelBuilder.Entity()
.HasOne(c=>c.Contract)
.带一个(c=>c.Car)
.HasForeignKey(c=>c.CarId);
}
这两种方法都在上下文的OnModelCreating方法中被调用。我终于设法解决了我的问题。 我已经在跟踪api控制器中的实体,如下所示:
[HttpPut("{id}")]
[Authorize(Roles = "Backoffice")]
public async Task<ActionResult<ContractDTO>> PutContract(int id, [FromBody] PutContractViewModel viewModel)
{
if (viewModel == null || !ModelState.IsValid)
return BadRequest(new { message = "Your model is wrong" });
var contract = await _contractService.GetContractDTO(id);
if (contract == null)
return NotFound();
var modifiedContract = await _contractService.UpdateContract(viewModel);
if (modifiedContract == null)
return BadRequest(new { message = "User or car may be busy in another contract" });
return Ok(modifiedContract);
}
[HttpPut(“{id}”)]
[授权(角色=“后台”)]
公共异步任务PutContract(int id,[FromBody]PutContractViewModel viewModel)
{
if(viewModel==null | |!ModelState.IsValid)
返回BadRequest(新建{message=“您的模型错误”});
var contract=await\u contractService.GetContractDTO(id);
如果(合同==null)
返回NotFound();
var modifiedContract=await _contractService.UpdateContract(viewModel);
if(modifiedContract==null)
return BadRequest(新建{message=“用户或车辆可能在另一个合同中忙碌”});
返回Ok(修改后的合同);
}
这种类型的方法适用于一对多关系,但显然,当您有一对一关系,并且必须创建表示同一实体的对象时,ChangeTracker无法正确跟踪更改。
如果有人突然遇到我的问题,我会发布我的新控制器和存储库代码。
控制器:
[HttpPut("{id}")]
[Authorize(Roles = "Backoffice")]
public async Task<ActionResult<ContractDTO>> PutContract(int id, [FromBody] PutContractViewModel viewModel)
{
if (viewModel == null || !ModelState.IsValid)
return BadRequest(new { message = "Your model is wrong" });
ContractDTO modifiedContract;
try
{
modifiedContract = await _contractService.UpdateContract(viewModel);
}
catch (EntityNotFoundException)
{
return NotFound();
}
if (modifiedContract == null)
return BadRequest(new { message = "User or car may be busy in another contract" });
return Ok(modifiedContract);
[HttpPut(“{id}”)]
[授权(角色=“后台”)]
公共异步任务PutContract(int id,[FromBody]PutContractViewModel viewModel)
{
if(viewModel==null | |!ModelState.IsValid)
返回BadRequest(新建{message=“您的模型错误”});
修改合同的合同;
尝试
{
modifiedContract=Wait_contractService.UpdateContact(viewModel);
}
捕获(EntityNotFoundException)
public async Task<Contract> Update(Contract entity)
{
var dbContract = await _context.Contracts.Include(c => c.User).Include(c => c.Car).FirstOrDefaultAsync(c => c.Id == entity.Id);
if (dbContract == null)
{
throw new EntityNotFoundException();
}
var dbUser = await _context.Users.Include(u => u.Contract).FirstOrDefaultAsync(u => u.Id == entity.UserId);
if (dbUser == null)
return null;
var dbCar = await _context.Cars.Include(c => c.Contract).FirstOrDefaultAsync(c => c.Id == entity.CarId);
if (dbCar == null)
return null;
dbContract.ExpiryDate = entity.ExpiryDate;
dbContract.MonthlyFee = entity.MonthlyFee;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateException)
{
return null;
}
return await GetById(entity.Id);
}