2014-05-24 135 views
0

我,他们都与'多到many`EF代码优先多对多更新

医生型号

public class Doctor 
{ 
    public int Id { get; set; } 
    [Required] 
    public string Fullname { get; set; } 
    public virtual List<Speciality> SelectedSpecialities { get; set; } 
    public virtual List<Speciality> AllSpecialities { get; set; } 
    public virtual List<int> PostedSpecialities { get; set; } 
    public Doctor() 
    { 
     SelectedSpecialities = new List<Speciality>(); 
     PostedSpecialities = new List<int>(); 
    } 
} 

特殊型号

public class Specialty 
{ 
    public int Id { get; set; } 
    [Required] 
    public string Title { get; set; } 
    public virtual List<Doctor> Doctors { get; set; } 
} 
两款车型

我也有这个流利的代码来创建多对多的关系。

modelBuilder.Entity<Speciality>().HasMany(x => x.Doctors).WithMany(x => x.SelectedSpecialities).Map(x => 
     { 
      x.ToTable("DoctorsSpecialities"); 
      x.MapLeftKey("SpecialityId"); 
      x.MapRightKey("DoctorId"); 
     }); 

我可以添加`Doctor`就好了,但是当我尝试'Update`医生的特色,它看起来像EF不会删除以前的关系。如果我有(1,2)和(1,3)并且想用(1,1)更新它,它不会删除(1,2)和(1,3)行,而我将有(1,1)(1,2)(1,3)在最后。

更新方法

[HttpPost] 
    public ActionResult Add(Doctor m) 
    { 
     if (ModelState.IsValid) 
     { 
      context.Entry(m).State = System.Data.Entity.EntityState.Modified; 
      m.SelectedSpecialities.Clear(); 
      // the line below returns a List<Specialty> of selected pecialties 
      m.SelectedSpecialities = context.Specialities.Where(x => m.PostedSpecialities.Contains(x.Id)).ToList(); 
      context.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 
     return View(); 
    } 
+0

我不是c#专家,但我认为你不是告诉代码删除以前的记录[(1,2)和(1,3)]并插入新的[(1,1)]或只是更新记录[(1,2)]到[(1,1)]。您只是编写代码来插入新记录。 –

+0

我认为EF应该将我的模型绑定到数据库,并且会负责删除这些行。 即使我想通过我自己删除这些行,我不知道如何。 – mhesabi

回答

0

问题是由事实,即在实体类并不是每一个属性是虚所致。尝试了这一点(对我的作品):

public class Doctor 
{ 
    public virtual int Id { get; set; } 
    public virtual string Fullname { get; set; } 
    public virtual ICollection<Specialty> SelectedSpecialities { get; set; } 
    public virtual ICollection<Specialty> AllSpecialities { get; set; } 
    public virtual ICollection<int> PostedSpecialities { get; set; } 
} 

public class Specialty 
{ 
    public virtual int Id { get; set; } 
    public virtual string Title { get; set; } 
    public virtual ICollection<Doctor> Doctors { get; set; } 
} 

public ActionResult Add(Doctor m) 
{ 
    if (ModelState.IsValid) 
    { 
     context.Entry(m).State = System.Data.Entity.EntityState.Modified; 
     m.SelectedSpecialities.Clear(); 
     // the line below returns a List<Specialty> of selected pecialties 
     foreach(var speciality in context.Specialties.Where(x => m.PostedSpecialities.Contains(x.Id))) 
     { 
      m.SelectedSpecialities.Add(speciality); 
     } 
     context.SaveChanges(); 
    } 
    return View(); 
} 

通过实体类虚拟制造的所有属性的实体可以通过EF机制进行跟踪,他们将正确初始化导航属性列表中没有你。通常您可以使用列表<>作为导航属性的类型,但我更喜欢使用ICollection,因为类不应该依赖于其他类,而应该依赖于接口。如果您使用PostSpecialities仅从视图获取值而不是将其存储在数据库中,那么我认为将它与存储在数据库中的属性混合并不是一个好主意。