我有两个与多对多相关的模型
医生型号
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`就好了,但是当我尝试`更新'医生的专业时,看起来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 :(得分: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机制跟踪实体,并且它们将在没有您的情况下初始化正确的导航属性列表。您通常可以使用List&lt;&gt;作为导航属性的类型,但我更喜欢使用ICollection,因为类不应该依赖于其他类,而是依赖于接口。如果你使用PostedSpecialities只从视图中获取值而不是将它存储在db中,那么我认为将它与存储在db中的属性混合起来并不是一个好主意。