.net-5 - 如何更新多对多关系中的现有对象(.Net 5)
问题描述
我一直在将 .Net 5 和 EF Core 5 用于小型 Web 应用程序。鉴于 EF Core 5 支持很多 - 许多开箱即用,因此不需要连接表。
更新数据库中已存在的对象时遇到问题。对于我的应用程序,我有很多关系的运动员和父母。
public class Athlete
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string MiddleName { get; set; }
public string Email { get; set; }
public string ContactNumber { get; set; }
public string Street { get; set; }
public int Postcode { get; set; }
public string City { get; set; }
public StateEnum State { get; set; }
public DateTime DateofBirth { get; set; }
public DateTime DateSignedUp {get; set;}
public virtual ICollection<Parent> Parents { get; set; }
}
public class Parent
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string MiddleName { get; set; }
public string Email { get; set; }
public string ContactNumber { get; set; }
public string Street { get; set; }
public int Postcode { get; set; }
public string City { get; set; }
public StateEnum State { get; set; }
public DateTime DateofBirth { get; set; }
public DateTime DateSignedUp {get; set;}
public virtual ICollection<Athlete> Athletes { get; set; }
}
当我尝试更新与另外两个父母有关系的现有运动员时,我收到一个错误:
违反主键约束“PK_AthleteParent”。无法在对象“dbo.AthleteParent”中插入重复键。重复键值为 (31, 1)
[HttpPost]
public async Task<ActionResult<Athlete>> PostAthlete(Athlete athlete)
{
_context.Athletes.Update(athlete);
await _context.SaveChangesAsync();
return Ok(athlete));
}
据我所知,当实体尝试更新我的 Athlete 时,它会尝试将新行插入到连接表中,即使父母已经存在于连接表中。有没有办法让实体在关系更新时删除任何记录?或者有没有办法告诉实体更新加入表以匹配传入的运动员对象?
解决方案
给出一个像这样的简单例子:
public class Foo {
Guid Id { get; set; }
ICollection<Bar> Bars { get; set; }
}
public class Bar {
Guid Id { get; set; }
ICollection<Foo> Foos { get; set; }
}
您可以调用clear()
的跟踪实例Foo
,然后重新添加Bar
要分配的实例。我发现这是避免约束异常的好方法 - 比手动尝试找出 Bars 发生了哪些变化要容易得多。
var foo = context.Foos.Include(x => x.Bars).FirstOrDefault(x => x.Id == someGuid);
foo.Bars.Clear();
foo.Bars.Add(bar1);
foo.Bars.Add(bar2);
...
context.Update(foo);
context.SaveChanges();
推荐阅读
- git - 无法在 GitLab CI/CD 中的作业之间传递工件
- android - 无法使用 Picasso (Android) 加载图像
- android-recyclerview - 分页库在 recyclerview 中没有显示任何内容
- django - 如何访问 django 中存储的用户数据?
- mongodb - 查询作为搜索值的子字符串的字段值
- php - 当用户通过雅虎应用程序登录时从雅虎获取用户电子邮件
- java - 是否可以在 Java 中调用 .NET Core 应用程序?
- c# - 如何在 C# 中的多列 ListView 中导入学生列表?
- python - 后台运行python,需要先接受用户输入
- encryption - 在 oracle 中加密和解密有困难