我在定义具有两个一对多关系(两个列表)
的实体时遇到问题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添加新约会时,我收到以下错误: 保存不公开其关系的外键属性的实体时发生错误。 EntityEntries属性将返回null,因为无法将单个实体标识为异常源。
我也试过这个映射而没有运气:错误0040:类型Calendar_FreeSlots未在名称空间Project.DAL(Alias = 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();
我想问题是我对同一类型的实体有两个一对多关系,但我不知道如何正确实现它。
答案 0 :(得分:3)
映射中的错误是您对两个不同的关系使用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)
提取日历条目的空闲位置。