多对多关系中的实体框架错误

时间:2013-04-02 00:12:45

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

我有以下课程用于约会:

public class Appointment
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int appointmentId { get; set; }

    public int Mins { get; set; }
    public DateTime StartDateTime { get; set; }
    public string Note { get; set; }

    //Navagation Properties
    public CompanyInformation Company { get; set; }

    public virtual ICollection<Service> Services { get; set; }

    public UserProfile Customer { get; set; }
    public UserProfile Staff { get; set; }

    public int? ParentID { get; set; }
    public Appointment ParentAppointment { get; set; }
}

以及以下服务类:

public class Service
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int serviceId { get; set; }
    public string name { get; set; }
    public string description { get; set; }
    public decimal price { get; set; }

    public bool isPublished { get; set; }
    public bool isActive { get; set; }

    public virtual CompanyInformation Company { get; set; }

    public UserProfile defaultStaff { get; set; }

    public virtual ICollection<Appointment> Appointments { get; set; }
}

我正试图通过以下方式在这两者之间创建多对多关系:

 modelBuilder.Entity<Service>().HasMany(e => e.Appointments).WithMany(e => e.Services);

在DbContext的OnModelCreating中。当我尝试更新数据库时,我收到以下错误。

 Introducing FOREIGN KEY constraint 'FK_dbo.ServiceAppointments_dbo.Appointments_Appointment_appointmentId' on table 'ServiceAppointments' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

无法创建约束。查看以前的错误。

我对它进行了一些研究,发现问题在于Cascade删除,我应该禁用它。问题是我不知道如何以及我发现的选项对我来说似乎不起作用(它们显然是为了一对多的关系)。任何帮助解决这个问题将不胜感激。提前谢谢....

2 个答案:

答案 0 :(得分:1)

这应该可以正常工作你不需要多对多的映射,按惯例工作)。 你有哪个版本的EF / CF?但无论如何,因为它没有......

a)尝试删除惯例,如提到的@Lajos - 应该这样做,

b)如果这不起作用,你可以'手动重写'关系 - 并关闭级联,就像这样......

modelBuilder.Entity<Appointment>()
    .HasOptional(x => x.ParentAppointment)
    .WithOptionalDependent()
    .WillCascadeOnDelete(false);

modelBuilder.Entity<ServiceAppointment>()
    .HasKey(x => new { x.ServiceId, x.AppointmentId });

modelBuilder.Entity<ServiceAppointment>()
    .HasRequired(x => x.Service)
    .WithMany(x => x.Appointments)
    .HasForeignKey(at => at.ServiceId)
    .WillCascadeOnDelete(false);

modelBuilder.Entity<ServiceAppointment>()
    .HasRequired(x => x.Appointment)
    .WithMany(x => x.Services)
    .HasForeignKey(at => at.AppointmentId)
    .WillCascadeOnDelete(false);

只需将两个类中的集合更改为...

// public virtual ICollection<Appointment> Appointments { get; set; }
public virtual ICollection<ServiceAppointment> Appointments { get; set; }

// public virtual ICollection<Service> Services { get; set; }
public virtual ICollection<ServiceAppointment> Services { get; set; }

public class ServiceAppointment
{
    public int ServiceId { get; set; }
    public int AppointmentId { get; set; }
    public Service Service { get; set; }
    public Appointment Appointment { get; set; }
}

......这绝对应该解决这个问题。虽然您丢失了“服务”'约会'直接导航(所有这些都通过ServiceAppointments)

答案 1 :(得分:0)

protected override void OnModelCreating( DbModelBuilder modelBuilder )
      {

         modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

     modelBuilder.Entity<Appointment>()
        .WithRequiredDependent()
        .WillCascadeOnDelete( false );

     modelBuilder.Entity<Service>()
        .WithRequiredDependent()
        .WillCascadeOnDelete( false );

      }