EF Code First dando problemas en claves externas

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 )

Tengo dos problemas: -

  1. No puedo obtener una relación de clave externa entre el estándar y los sujetos, dice que la relación causará varias rutas de eliminación en cascada ...

  2. si hago una relación de clave externa entre la prueba y el detalle de uso, me da el problema anterior para mapear la tabla tst_question.

Además, como soy nuevo en el código EF primero, señale mis errores. Toda la ayuda y la discusión son bienvenidas.

preguntado el 27 de agosto de 11 a las 18:08

1 Respuestas

De forma predeterminada, EF creará claves externas cascade delete. En su modelo, si elimina un Standard hay varias rutas para eliminar el QuestionDescriptor.

Estándar -> QuestionDescriptor

y

Estándar -> Asunto -> QuestionDescriptor

Es por eso que el servidor SQL no le permite hacer esto. Ver esta respuesta para más detalles

Lo que puede hacer es decirle explícitamente a EF que cree claves externas sin cascade delete. Pero esto puede crear problemas de integridad de los datos. Así que asegúrese de comprender las consecuencias.

Lo que puede hacer es configurar las relaciones usando una API fluida con WillCascadeOnDelete(false).

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

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

contestado el 23 de mayo de 17 a las 15:05

Muchas gracias por su ayuda. Quiero la clave externa entre estándar y sujeto a cascada también, ya que el sujeto depende del estándar. ¿No puedo tener múltiples rutas, porque no veo ningún ciclo allí? - ashutosh raina

@ashutosh luego configurar Standard -> QuestionDescriptor sin cascada. Es posible que deba agregar un activador para realizar la eliminación. Experimente lo que funciona bien para usted. - Eranga

sí ... estoy de acuerdo contigo. ¿Crees que es mejor si mantengo toda mi lógica de mapeo separada y uso una API fluida en lugar de anotaciones? - ashutosh raina

@ashutosh hay pros y contras en ambos enfoques. Las configuraciones basadas en atributos son muy limitadas. Usaría una API fluida para mapeos. - Eranga

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.