Dun*_*can 8 c# many-to-many entity-framework ef-code-first dbcontext
假设我在Entity Framework Code-First设置中有以下模型类:
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Team> Teams { get; set; }
}
public class Team
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Person> People { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
从此代码创建的数据库包括一个TeamPersons表,表示人员和团队之间的多对多关系.
现在假设我有一个断开连接的Person对象(不是代理,但尚未附加到上下文),其Teams集合包含一个或多个断开连接的Team对象,所有这些对象都代表已存在于数据库中的团队.例如,如果具有Id 1的Person和具有Id 3的Team已存在于db中,则由以下内容创建的对象:
var person = new Person
{
Id = 1,
Name = "Bob",
Teams = new HashSet<Team>
{
new Team { Id = 3, Name = "C Team"}
}
};
Run Code Online (Sandbox Code Playgroud)
更新此对象的最佳方法是什么,以便在更新后TeamPersons表包含Bob的单行,将他链接到C Team?我试过了明显的事:
using (var context = new TestContext())
{
context.Entry(person).State = EntityState.Modified;
context.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)
但是Teams系列被这个忽略了.我也尝试了其他各种各样的东西,但似乎没有什么能像我在这里完成的那样.谢谢你的帮助.
编辑:
所以我得到了我可以从数据库中获取Person和Team [s],更新它们然后提交更改:
using (var context = new TestContext())
{
var dbPerson = context.People.Find(person.Id);
dbPerson.Name = person.Name;
dbPerson.Teams.Clear();
foreach (var id in person.Teams.Select(x => x.Id))
{
var team = context.Teams.Find(id);
dbPerson.Teams.Add(team);
}
context.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)
但是,如果Person是一个复杂的实体,那将是一种痛苦.我知道我可以使用Automapper或其他东西使事情变得更容易,但如果没有办法保存原始人物对象,而不是必须得到一个新的并且复制所有属性,那么看起来仍然是一种耻辱......
Team一般方法是从数据库中获取并将Add其放入 的Person集合中Teams。设置EntityState.Modified仅影响标量属性,而不影响导航属性。