J'essaie donc actuellement de créer une première migration de code avec Entity Framework Core pour un tableau qui affiche les conférences terminées par l'utilisateur de l'application. Mon modèle ressemble à ceci:
public class LectureCompletion
{
[Key, Column(Order = 0)]
[ForeignKey("Lecture")]
public Lecture LectureId { get; set; }
[Key, Column(Order = 1)]
[ForeignKey("User")]
public ApplicationUser UserId{ get; set; }
public bool Completed { get; set; }
}
Je veux utiliser le UserId
et le LectureId
comme clé composite unique. Cependant, j'obtiens cette erreur:
Le type d'entité 'LectureCompletion' nécessite la définition d'une clé primaire.
Je ne comprends pas pourquoi cela se produit car j'ai clairement mes attributs clés dans les positions correctes? Puis-je utiliser ApplicationUser
comme clé étrangère/primaire?
Voici mon modèle Lecture
:
public class Lecture
{
[Key]
public int LectureId { get; set; }
public string ModuleName { get; set; }
public string LectureName { get; set; }
}
Et mon ApplicationDBContext.cs
:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public DbSet<Lecture> Lectures { get; set; }
public DbSet<LectureCompletion> LectureCompletion { get; set; }
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Customize the ASP.NET Identity model and override the defaults if needed.
// For example, you can rename the ASP.NET Identity table names and more.
// Add your customizations after calling base.OnModelCreating(builder);
}
}
Vous ne pouvez pas définir une clé compoiste avec une annotation de données uniquement. Vous devez utiliser à la place l'API Fluent.
public class LectureCompletion
{
// which is your case.
[ForeignKey(nameof(Lecture))]
public int LectureId { get;set; }
public Lecture Lecture { get; set; }
[ForeignKey(nameof(ApplicationUser))]
public int UserId {get;set;}
public ApplicationUser ApplicationUser { get; set; }
public bool Completed { get; set; }
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Define composite key.
builder.Entity<LectureCompletion>()
.HasKey(lc => new { lc.LectureId, lc.UserId });
}
Votre classe LectureCompletion
a besoin d'une clé primaire pour être définie correctement .[Key]
est l'annotation de clé primaire pour indiquer explicitement à EntityFramework de la définir comme clé primaire, sinon la convention prendra le relais.
Autrement dit, les propriétés nommées soit ID
ou suffixées avec ID
, par exemple PokemonID
pour la table Pokemon
. ID
ou Id
n'est pas sensible à la casse dans ce cas.
L'attribut de clé étrangère n'est utilisé que si vous souhaitez que le nom de votre propriété de clé étrangère dans la classe LectureCompletion
soit nommé différemment de votre classe référencée. Par exemple, si la clé primaire de votre classe ApplicationUser
est ApplicationUserId
, mais dans la classe LectureCompletion
vous voulez qu'elle soit UserId
, vous pouvez ajouter l'attribut.
Fais-le comme ça
public class LectureCompletion
{
[Key] // Defined only once
public LectureCompletionId { get;set; }
// Not needed if Lecture class has the primary key property of LectureId,
// which is your case.
[ForeignKey("Lecture")] // Name of your navigation property below.
public int LectureId { get;set; }
public Lecture Lecture { get; set; }
[ForeignKey("ApplicationUser")]
public int UserId {get;set;}
public ApplicationUser ApplicationUser { get; set; }
public bool Completed { get; set; }
}
En ce qui concerne EntityFramework Core, le ColumnOrder ne semble pas avoir d'effet pour l'instant.