实体框架,代码优先,更新独立关联(集合)

时间:2015-06-18 08:16:24

标签: c# entity-framework collections ef-code-first

解释问题我有一个类Person的简单模型:

public class Person
{
    public int Id { get; set; }

    public virtual string Name { get; set; }
}

和一个有人员集合的学校:

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();
        }

并在人员表中正确设置了school_id外键:

Id     Name    School_Id

1      Thomas     1 
2      Markus     1  

但是当我尝试添加一个新的学生时:

using (DatabaseContext ctx = new DatabaseContext())
        {
            Person p = new Person() { Name = "Mark" };
            s.Pupils.Add(p);
            ctx.Persons.Add(p);
            ctx.SaveChanges();
        }

在数据库表中将School_id设置为null:

 Id     Name    School_Id

 1      Thomas     1 
 2      Markus     1  
 3      Mark      null  

我做错了什么?我知道我可以使用外键关联,但由于我打算使用不同相关实体的Person Entity,我更喜欢独立关联。

感谢您的帮助!!

2 个答案:

答案 0 :(得分:0)

当你创建你的poco时,你的Pupils集合是空的(即使是Set.Add(Set.Create()),也可以将你的学校重写为:

private HashSet<Person> _pupils

public ICollection<Person> Pupils { 
  get {return _pupils ?? (_pupils = new HashSet<Person>());}
  set{_pupils = value;} 
}

编辑:我现在注意到你有s.Pupils.Add(p);(但我看不到你得到的地方s) - 你是否真的以这种方式使用它?它应该抛出null异常...或者任何机会,你的代理创建是否被禁用? (它应该启用;))

Edit2: s.Pupils = new ObservableCollection<Person>(); - 您几乎丢弃了EF生成的代理集合,因此不会跟踪任何.Add()并且不会将更改推送到FK属性(您的{{1是} p.School

答案 1 :(得分:0)

听起来像s没有附加到你应该拥有的dbcontext

s = ctx.Set<School>().Where(x => x.Id == 1).First();

请注意1是硬编码值,您应该根据应用程序上下文设置一个变量。

请注意,如果Jan的建议不能解决您的具体问题,那么他的建议是好的,应该实施。