我首先通过以下方式在我的对象“Resto”和“OpeningTimes”之间创建了“一对多”关系:
在我的模型中:
[Table("Resto")] public class Resto { public int Id { get; set; } public string Name { get; set; } public string PhoneNumber { get; set; } public string Address { get; set; } //TODO Ajouter adresse détaillées public virtual ICollection<SlotTime> OpeningTimes {get; set;} public virtual ICollection<ApplicationUser> Administrators { get; set; } public virtual ICollection<ApplicationUser> Chefs { get; set; } public virtual Menu Menu {get; set;} } [Table("RestoSlotTimes")] public class SlotTime { public int SlotTimeId { get; set; } public DayOfWeek DayOfWeek { get; set; } public TimeSpan OpenTime { get; set; } public TimeSpan CloseTime { get; set; } public int RestoId { get; set; } public virtual Resto Resto { get; set; } }
由于我有来自该对象的其他关系(请参阅应用程序用户中的那个),我也使用Fluent语言来消除歧义.
方式如下:
modelBuilder.Entity<Resto>() .HasMany<ApplicationUser>(s => s.Administrators) .WithMany(c => c.Resto_Admin) .Map(cs => { cs.MapLeftKey("Resto_Admin"); cs.MapRightKey("Admin"); cs.ToTable("RestosAdmins"); }); modelBuilder.Entity<Resto>() .HasMany<ApplicationUser>(s => s.Chefs) .WithMany(c => c.Resto_Chefs) .Map(cs => { cs.MapLeftKey("Resto_Chefs"); cs.MapRightKey("Chef"); cs.ToTable("RestosChefs"); }); modelBuilder.Entity<Resto>() .HasOptional(s => s.Menu) .WithRequired(ad => ad.resto) .WillCascadeOnDelete(true);
但这些关系工作正常.
今天我在我的控制器中对我的“OpeningTimes”进行基本操作,因为在DB中添加了以下项目:
[HttpPost] public async Task<ActionResult> AddSlotTimeToRestaurant(AddSlotTimeToRestaurantView model) { var resto = await DbManager.Restos.FirstAsync(r => r.Id == model.RestoId); if(resto != null) { if(model.OpenTimeId < model.CloseTimeId) { SlotTime slotTime = new SlotTime() { DayOfWeek = model.Day, OpenTime = model.SlotTimeList.timeSpanViews.FirstOrDefault(m => m.Id == model.OpenTimeId).TimeSpan, CloseTime = model.SlotTimeList.timeSpanViews.FirstOrDefault(m => m.Id == model.CloseTimeId).TimeSpan }; resto.OpeningTimes.Add(slotTime); await DbManager.SaveChangesAsync(); return RedirectToAction("edit", new { id = model.RestoId }); } else { ModelState.AddModelError("SelectedSlotTimeId_1_Stop", "L'heure de fermeture doit être après l'heure d'ouverture"); return View(); } } return new HttpStatusCodeResult(HttpStatusCode.BadRequest); }
此代码按预期工作.
但现在我尝试使用以下代码执行另一个删除对象的功能:
public async Task<ActionResult> RemoveSlotTimeToRestaurant(int RestoId, int SlotId) { var resto = await DbManager.Restos.FirstAsync(r => r.Id == RestoId); if (resto != null) { SlotTime slotTime = resto.OpeningTimes.FirstOrDefault(m => m.SlotTimeId == SlotId); if(slotTime != null) { resto.OpeningTimes.Remove(slotTime); await DbManager.SaveChangesAsync(); return RedirectToAction("edit", new { id = RestoId }); } } return new HttpStatusCodeResult(HttpStatusCode.BadRequest); }
我在DbSave线上有一个错误……看起来它看起来像EF试图不删除我的对象而只是保留它并将其ID设置为Null …这不是我所期望的
The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted
我觉得我的关系配置好EF.我觉得要正确地添加和删除关系……
你认为这可以来自流畅的配置吗?
BTW一旦我删除了“Resto”,我的级联删除工作得很好,我的所有项目“OpeningTimes”都被很好地删除了DB而没有错误.
最好的祝福,
如果您希望能够通过父实体(Resto)修改子实体(OpeningTimes),则需要在模型构建器中指定两者之间的关系:modelBuilder.Entity<Resto>() .HasMany(r => r.OpeningTimes) .WithOptional() .HasForeignKey(ot => ot.RestoId)
This blog post详细介绍了处理这种情况.
另一种方法是直接从DbContext上定义的DbSet中删除实体:
DbManager.SlotTimes.Remove(slotTime);