1

我有界定有两个一个一对多的关系(两个列表)多一个相同的实体类型代码的许多关系第一

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(); 

我想这个问题是我有两个一个一对多的关系,同一类型的实体,但我不知道做正确的方式。

回答

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.AppointmentsAppointment中的一种状态,就像bool IsFree属性一样。然后您可以始终使用calendar.Appointments.Where(a => a.IsFree)提取日历项的空闲插槽。

+0

谢谢@Slauma!这解决了我的问题。你对bool属性是正确的,实际上我使用了两个不同的实体,它们是从Appointment继承而来的。无论如何,我不明白哪个是我的映射问题,但现在我:) – moarra

+0

我正在尝试做类似的事情。我有一个有电子邮件和电话的联系人。我想将电子邮件和电话结合在一个名为CONTACTINFO的实体中,该实体可以具有ContactInfoType属性(Enum)来区分它们。如果有一种方法在模型构建器中使用默认的WHERE子句/条件来导航属性? – Yashvit

相关问题