0

Ces jours-ci, j'ai travaillé sur l'héritage avec Entity Framwork 6 (MVC, VisualStudio 2015, code-first). En essayant différents aspects, j'ai trouvé le besoin de générer une PrimaryKey qui identifie la sous-classe, séparée de la primaryKey/ForeignKey qui hérite de la classe parente. L'idée que je veux développer est celui-ci:Ajouter PK sur une sous-classe (héritage) différente de l'ID de la classe parente

public class Person 
{ 

    [Key] 
    public int PersonId { get; set; } 

} 

public class Student : Person 
{ 

    [Key] 
    public int StudentId { get; set; } 

} 

Je suis seraching pour d'autres personnes qui ont essayé cela, mais je ne trouve rien. Je ne suis pas sûr si c'est possible de le faire ou pas, donc si quelqu'un peut m'aider, je vais l'apprécier beaucoup

Merci.

+1

Vous n'êtes pas sûr de pouvoir le faire avec des annotations de données, cependant ... pourquoi voulez-vous faire cela? Avoir un nom cohérent pour votre PK est très utile. – DavidG

Répondre

1

Si vous décrivez un Student, et vous auriez besoin de décrire la signification de Student.StudentId et Student.PersonId, pourriez-vous donner une description correcte?

Il me semble que la seule raison pour laquelle vous voulez donner à une Etudiante une nouvelle propriété pour la clé primaire à cause de l'Identifiant de cette propriété, et non à cause d'une véritable signification propre.

La méthode que vous devez utiliser pour modéliser l'héritage dans Entity Framework dépend du type de requêtes que vous utiliserez le plus souvent. Supposons que vous avez trois types de personnes: les étudiants, les enseignants et les parents. Pensez à quel type de requêtes que vous le plus souvent faire:

  1. -vous le plus souvent demander pour les étudiants qui ont ... ou parents ...
  2. Ou allez-vous le plus souvent pour les personnes que .. . et rarement pour les étudiants qui ... ou enseignants qui ...

(1) demander Surtout pour les étudiants qui ...: Utilisez TPC

Si vous le modèle de votre stratégie d'héritage comme Table per Concrete Class (TPC), puis étudiants, enseignants et Les parents auront chacun leur propre table. Il n'y a pas de table commune des parents. Toutes les propriétés parent d'un étudiant se trouvent dans les tables Étudiants et toutes ces propriétés parent sont également dans la table Enseignants.

Cette stratégie d'héritage est la meilleure si vous demandez surtout aux étudiants qui ... et rarement aux personnes qui ... utilisant TPC de demander aux étudiants qui ... auront seulement besoin d'une table. Demander aux personnes qui ... auront toujours besoin de la concaténation des résultats des requêtes sur les étudiants qui ... et les enseignants qui ... et les parents qui ...

Je trouve que c'est la stratégie de succession que je le plus souvent utilisation.

(2) demander Surtout pour les personnes qui ...: Utilisez TPT

Si ce sont les requêtes les plus utilisées, il est préférable de modéliser toutes les données de personne dans un tableau distinct et laisser les élèves, les enseignants et les parents ont tous une référence à leurs données personne: Table-Per-Type (TPT)

Comment mettre en œuvre TPC

Si vous implémentez l'héritage selon PTC, alors il n'y aura pas une table de personne distincte. Pas besoin de donner un ID aux personnes.

class Person 
{ 
    public string FirstName {get; set;} 
    ... 
} 

class Student : Person 
{ 
    public int Id {get; set;} 
    ... 
} 

class Teacher : Person 
{ 
    public int Id{get; set; 
    ... 
} 

Si vous prévoyez de ne jamais instancier une personne, seuls les étudiants, les enseignants et les parents, condsder ​​déclarant la classe personne abstraite

Par ailleurs, si vous donnez la propriété clé primaire le nom par défaut Id, entité Le cadre saura que cela devrait être votre clé primaire. Pas besoin d'attributs, ni d'API fluide.

Dans votre DbContext:

class MyDbContext : DbContext 
{ 
    public DbSet<Student> Students {get; set;} 
    public DbSet<Teacher> Teachers {get; set;} 
    public DbSet<Parent> Parents {get; set;} 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<Student>().Map(student => 
     { 
      student.MapInheritedProperties(); 
      student.ToTable(nameof(MyDbContext.Students)); 
     }); 

     modelBuilder.Entity<Teacher>().Map(teacher => 
     { 
      teacher.MapInheritedProperties(); 
      teacher.ToTable(nameof(MyDbContext.Teachers)); 
     }); 
     // etc. for Parent 
    } 
} 

Comment mettre en œuvre TPT

Il y aura une table personnes, et les étudiants et les enseignants se référera à la table personnes.

class Person 
{ 
    public int Id {get;set;} 
    ... 
} 
class Student 
{ 
    public int Id {get;set;} 
    // A student has Person data via foreign key: 
    public int PersonId {get; set;} 
    public Person Person {get; set;} 
    ...   
} 
class Teacher 
{ 
    public int Id {get;set;} 
    // A Teacher has Person data via foreign key: 
    public int PersonId {get; set;} 
    public Person Person {get; set;} 
    ...   
} 
+0

Merci pour votre aide !! finalement implémenté le (2), je trouve que si vous ne déclarez pas un PK sur la classe de base, alors vous pouvez définir votre propre PK dans la sous-classe. Mais vous ne pouvez pas le faire avec TPT vous devez implémenter TPH –