如何更新多对多关系中的现有 object (.Net 5)
How to update an existing object in a many to many relationship (.Net 5)
我一直在将 .Net 5 和 EF Core 5 用于小型 Web 应用程序。鉴于 EF Core 5 支持许多开箱即用的功能,因此无需加入 table.
我在更新数据库中已存在的 object 时遇到了问题 运行。对于我的应用程序,我有 Athletes 和 Parents,它们有很多关系。
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; }
}
当我尝试更新与其他两个 parents 有关系的现有运动员时,我收到错误消息:
Violation of PRIMARY KEY constraint 'PK_AthleteParent'. Cannot insert
duplicate key in object 'dbo.AthleteParent'. The duplicate key value
is (31, 1)
[HttpPost]
public async Task<ActionResult<Athlete>> PostAthlete(Athlete athlete)
{
_context.Athletes.Update(athlete);
await _context.SaveChangesAsync();
return Ok(athlete));
}
据我所知,当实体尝试更新我的 Athlete 时,它会尝试将新行插入连接 table,即使 parents 已经存在于其中。有没有办法让实体在更新关系时删除任何记录?或者有没有办法告诉实体更新加入 table 以匹配传入的运动员 object?
给出一个像这样的简单例子:
public class Foo {
Guid Id { get; set; }
ICollection<Bar> Bars { get; set; }
}
public class Bar {
Guid Id { get; set; }
ICollection<Foo> Foos { get; set; }
}
您可以在 Foo
的跟踪实例上调用 clear()
,然后重新添加要分配的 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();
我一直在将 .Net 5 和 EF Core 5 用于小型 Web 应用程序。鉴于 EF Core 5 支持许多开箱即用的功能,因此无需加入 table.
我在更新数据库中已存在的 object 时遇到了问题 运行。对于我的应用程序,我有 Athletes 和 Parents,它们有很多关系。
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; }
}
当我尝试更新与其他两个 parents 有关系的现有运动员时,我收到错误消息:
Violation of PRIMARY KEY constraint 'PK_AthleteParent'. Cannot insert duplicate key in object 'dbo.AthleteParent'. The duplicate key value is (31, 1)
[HttpPost]
public async Task<ActionResult<Athlete>> PostAthlete(Athlete athlete)
{
_context.Athletes.Update(athlete);
await _context.SaveChangesAsync();
return Ok(athlete));
}
据我所知,当实体尝试更新我的 Athlete 时,它会尝试将新行插入连接 table,即使 parents 已经存在于其中。有没有办法让实体在更新关系时删除任何记录?或者有没有办法告诉实体更新加入 table 以匹配传入的运动员 object?
给出一个像这样的简单例子:
public class Foo {
Guid Id { get; set; }
ICollection<Bar> Bars { get; set; }
}
public class Bar {
Guid Id { get; set; }
ICollection<Foo> Foos { get; set; }
}
您可以在 Foo
的跟踪实例上调用 clear()
,然后重新添加要分配的 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();