EF Code First给出外键问题

时间:2011-08-27 18:47:51

标签: entity-framework-4 ef-code-first

public class ParikshaContext :DbContext
{
    public ParikshaContext()
    {

       Database.SetInitializer(new DropCreateDatabaseIfModelChanges<ParikshaContext>());

    }
    public DbSet<UserDetail> UserDetails { get; set; }
    public DbSet<Standard> Standards { get; set; }
    public DbSet<Subject> Subjects { get; set; }
    public DbSet<QuestionDescriptor> QuestionDescriptors { get; set; }
    public DbSet<QuestionBrief> QuestionBriefs { get; set; }
    public DbSet<QuestionCustom> QuestionCustoms { get; set; }
    public DbSet<QuestionChoice> QuestionChoices { get; set; }
    public DbSet<QuestionMatch> QuestionMatches { get; set; }
    public DbSet<Test> Tests { get; set; }
    public DbSet<Test_Question> Test_Questions { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<QuestionCustom>().ToTable("Custom");
        modelBuilder.Entity<QuestionBrief>().ToTable("Brief");
        modelBuilder.Entity<QuestionMatch>().ToTable("Match");
        modelBuilder.Entity<QuestionChoice>().ToTable("Choice");
    }       
} 

public class QuestionDescriptor
{

    public int QuestionDescriptorId { get; set; } 

    public int StandardId { get; set; }
    [ForeignKey("StandardId")]
    public virtual Standard Standard { get; set; }

    public int SubjectId { get; set; }
    [ForeignKey("SubjectId")]
    public virtual Subject Subject { get; set; }

    public int Rating { get; set; }
    public int Difficulty { get; set; }

    public DateTime DateOfCreation{get;set;}

    public int UserDetailId { get; set; }     
    [ForeignKeyAttribute("UserDetailId")]
    public virtual UserDetail Creator { get; set; }

}

public class QuestionBrief : QuestionDescriptor
{
    public String QuestionText { get; set; }
    public String Answer { get; set; }
    //true for fill in the blanks and false for a loing answers
    public bool Short { get; set; }
}

public class Standard
{
    public int StandardId { get; set; }
    public String StandardName { get; set; }

}

public class Subject
{
    public int SubjectId { get; set; }
    public String SubjectName { get; set; }
    public String SubjectCategory { get; set; }        

  //  public int StandardId { get; set; }
  //  [ForeignKey("StandardId")]
   // public virtual Standard Standard { get; set; }
}

public class Test
{

    public int TestID { get; set; }
    public DateTime DateOfCreation { get; set; }    

    public String StandardName { get; set; }
    public String SubjectName { get; set; }
    public String SubjectCategory { get; set; }

//    public int UserDetailId { get; set; }
//    [ForeignKey("UserDetailId")]
 //   public virtual UserDetail Creator { get; set; }


}

public class Test_Question
{

    public int Test_QuestionID { get; set; }     

    public int TestId { get; set; }
    [ForeignKey("TestId")]
    public virtual Test Test { get; set; }

    public int QuestionDescriptorId { get; set; }
    [ForeignKey("QuestionDescriptorId")]
    public virtual QuestionDescriptor Question { get; set; }
}

public class UserDetail
{

    public int UserDetailId { get; set; }

    [Required]
    [MaxLength(10, ErrorMessage = "UserName must be 10 characters or less"), MinLength(5)]
    public String Name { get; set; }

    [Required]        
    public String Password { get; set; }
    public String UserRole { get; set; }
    public DateTime DateOfCreation{  get; set;}    
}

//Match,Custom,Choice classes have been omitted for lack of space (which sounds stupid when i look at the amount of code i have pasted )

我有两个问题: -

  1. 我无法获得标准和主题之间的外键关系,它说这种关系会导致几个级联删除路径......

  2. 如果我在test和usedetail之间进行外键关系,它会给我上面的映射tst_question表的问题。

  3. 此外,由于我是EF代码的新手,请指出我的错误。欢迎所有帮助和讨论。

1 个答案:

答案 0 :(得分:2)

默认情况下,EF会创建外键cascade delete。在您的模型中,如果删除Standard,则有多个路径可以删除QuestionDescriptor

  

标准 - &gt; QuestionDescriptor

  

标准 - &gt;主题 - &gt; QuestionDescriptor

这就是SQL Server不允许您这样做的原因。见this answer for more details

您可以做的是明确告诉EF创建没有cascade delete的外键。 但这可能会造成数据完整性问题。因此,请确保您了解后果。

您可以做的是使用带有WillCascadeOnDelete(false)的流畅API配置关系。

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
  //other mappings

      modelBuilder.Entity<Subject>()
        .HasRequired(subject => subject.Standard).WithMany()
        .HasForeignKey(subject => subject.StandardId)
        .WillCascadeOnDelete(false);
}