>我在定义具有两个一对多关系(两个列表)的实体时遇到问题
public class Calendar
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public Guid ID { get; set; }
public virtual IList<Appointment> FreeSlots { get; set; }
public virtual IList<Appointment> AppointmentsList { get; set; }
...
}
public class Appointment
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int AppointmentID { get; set; }
public DateTime Start { get; set; }
public DateTime End { get; set; }
public String Type { get; set; }
public String Info { get; set; }
public Guid CalendarID { get; set; }
public virtual Calendar Calendar { get; set; }
}
和代码优先代码:
modelBuilder.Entity<Appointment>().HasKey(u => new {u.AppointmentID, u.CalendarID });
modelBuilder.Entity<Appointment>().HasRequired(u => u.Calendar).WithMany(c => c.FreeSlots).HasForeignKey(f => f.CalendarID).WillCascadeOnDelete(true);
modelBuilder.Entity<Appointment>().HasRequired(u => u.Calendar).WithMany(c => c.AppointmentsList).HasForeignKey(f => f.CalendarID).WillCascadeOnDelete(true);
约会有两个PK,因为如果日历被删除,我希望删除约会。
当我尝试将新约会添加到 FreeSlot 时,出现以下错误:保存未公开其关系的外键属性的实体时出错。属性将返回 null,因为无法将单个实体标识为异常的来源。
我也尝试过这个映射,但没有运气:错误 0040:类型 Calendar_FreeSlots 未在命名空间 Project.DAL (别名 = Self) 中定义。
modelBuilder.Entity<Appointment>().HasKey(u => new {u.AppointmentID, u.CalendarID });
modelBuilder.Entity<Calendar>().HasMany(c => c.FreeSlots).WithRequired(c => c.Calendar).HasForeignKey(c => c.CalendarID).WillCascadeOnDelete();
modelBuilder.Entity<Calendar>().HasMany(c => c.AppointmentsList).WithRequired(c => c.Calendar).HasForeignKey(c => c.CalendarID).WillCascadeOnDelete();
我想问题是我对同一类型的实体有两个一对多关系,但我不知道正确制作它的方法。
中的错误是将Appointment.Calendar
用于两个不同的关系。那是不可能的。您需要在Appointment
中第二对 FK 和导航属性(或映射一个没有反向属性的关系):
modelBuilder.Entity<Calendar>()
.HasMany(c => c.FreeSlots)
.WithRequired(c => c.Calendar1)
.HasForeignKey(c => c.Calendar1ID)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Calendar>()
.HasMany(c => c.AppointmentsList)
.WithRequired(c => c.Calendar2)
.HasForeignKey(c => c.Calendar2ID)
.WillCascadeOnDelete(true);
(对于至少一个关系,必须禁用级联删除。否则,最终会出现多个级联删除异常。
但是,我有一种感觉,你实际上应该只有一个关系和收藏Calendar.Appointments
,以及Appointment
中的一种地位,就像bool IsFree
财产一样。然后,您始终可以使用calendar.Appointments.Where(a => a.IsFree)
提取日历条目的空闲插槽。