首先是同一实体类型代码的多个一对多关系

时间:2014-02-19 15:57:31

标签: asp.net-mvc-4 ef-code-first entity-framework-5 code-first

我在定义具有两个一对多关系(两个列表)

的实体时遇到问题
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();

我想问题是我对同一类型的实体有两个一对多关系,但我不知道如何正确实现它。

1 个答案:

答案 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)提取日历条目的空闲位置。