Entity Framework,Code First,更新独立关联(合集)
Entity Framework, Code First, Update independent association (Collection)
为了解释这个问题,我有一个简单的模型,其中有一个 class 人:
public class Person
{
public int Id { get; set; }
public virtual string Name { get; set; }
}
和一所 class 学校,其中有一群人:
public class School
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Person> Pupils { get; set; }
}
创建学校效果很好:
using (DatabaseContext ctx = new DatabaseContext())
{
Person p = new Person() { Name = "Thomas" };
Person p2 = new Person() { Name = "Markus" };
School s = new School();
s.Name = "Test";
s.Pupils = new ObservableCollection<Person>();
s.Pupils.Add(p);
s.Pupils.Add(p2);
ctx.Schools.Add(s);
ctx.SaveChanges();
}
并且在人 table 中 school_id 外键设置正确:
Id Name School_Id
1 Thomas 1
2 Markus 1
但是当我尝试添加新的 Pupil 时:
using (DatabaseContext ctx = new DatabaseContext())
{
Person p = new Person() { Name = "Mark" };
s.Pupils.Add(p);
ctx.Persons.Add(p);
ctx.SaveChanges();
}
School_id 在数据库中设置为 null table:
Id Name School_Id
1 Thomas 1
2 Markus 1
3 Mark null
我做错了什么?我知道我可以使用外键关联,但因为我打算将个人实体与不同的相关实体一起使用,所以我更喜欢独立关联。
感谢您的帮助!!
因为当您创建 poco 时您的 Pupils 集合为空(即使通过 Set.Add(Set.Create())
,将您的 School poco 重写为:
private HashSet<Person> _pupils
public ICollection<Person> Pupils {
get {return _pupils ?? (_pupils = new HashSet<Person>());}
set{_pupils = value;}
}
编辑: 我刚刚注意到你有 s.Pupils.Add(p);
(但我没看到你从哪里得到 s
)——你真的是这样使用它的吗?它应该抛出空异常......或者有任何机会,你的代理创建被禁用了吗? (应该启用它;))
Edit2: s.Pupils = new ObservableCollection<Person>();
-- 您实际上丢弃了 EF 生成的代理集合,因此不会跟踪任何 .Add() 并且不会将更改推送到 FK 属性(你的p.School
是null
)
听起来 s 没有附加到您应该具有的 dbcontext
s = ctx.Set<School>().Where(x => x.Id == 1).First();
请注意 1 是一个硬编码值,您应该根据应用程序上下文设置一个变量值。
另请注意,如果 Jan 的建议不能解决您的具体问题,他的建议很好,应该实施。
为了解释这个问题,我有一个简单的模型,其中有一个 class 人:
public class Person
{
public int Id { get; set; }
public virtual string Name { get; set; }
}
和一所 class 学校,其中有一群人:
public class School
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Person> Pupils { get; set; }
}
创建学校效果很好:
using (DatabaseContext ctx = new DatabaseContext())
{
Person p = new Person() { Name = "Thomas" };
Person p2 = new Person() { Name = "Markus" };
School s = new School();
s.Name = "Test";
s.Pupils = new ObservableCollection<Person>();
s.Pupils.Add(p);
s.Pupils.Add(p2);
ctx.Schools.Add(s);
ctx.SaveChanges();
}
并且在人 table 中 school_id 外键设置正确:
Id Name School_Id
1 Thomas 1
2 Markus 1
但是当我尝试添加新的 Pupil 时:
using (DatabaseContext ctx = new DatabaseContext())
{
Person p = new Person() { Name = "Mark" };
s.Pupils.Add(p);
ctx.Persons.Add(p);
ctx.SaveChanges();
}
School_id 在数据库中设置为 null table:
Id Name School_Id
1 Thomas 1
2 Markus 1
3 Mark null
我做错了什么?我知道我可以使用外键关联,但因为我打算将个人实体与不同的相关实体一起使用,所以我更喜欢独立关联。
感谢您的帮助!!
因为当您创建 poco 时您的 Pupils 集合为空(即使通过 Set.Add(Set.Create())
,将您的 School poco 重写为:
private HashSet<Person> _pupils
public ICollection<Person> Pupils {
get {return _pupils ?? (_pupils = new HashSet<Person>());}
set{_pupils = value;}
}
编辑: 我刚刚注意到你有 s.Pupils.Add(p);
(但我没看到你从哪里得到 s
)——你真的是这样使用它的吗?它应该抛出空异常......或者有任何机会,你的代理创建被禁用了吗? (应该启用它;))
Edit2: s.Pupils = new ObservableCollection<Person>();
-- 您实际上丢弃了 EF 生成的代理集合,因此不会跟踪任何 .Add() 并且不会将更改推送到 FK 属性(你的p.School
是null
)
听起来 s 没有附加到您应该具有的 dbcontext
s = ctx.Set<School>().Where(x => x.Id == 1).First();
请注意 1 是一个硬编码值,您应该根据应用程序上下文设置一个变量值。
另请注意,如果 Jan 的建议不能解决您的具体问题,他的建议很好,应该实施。