Ho questa entità:
[Table("order")]
public class Order
{
[Key]
[Column("id")]
public Guid Id { get; set; }
[MaxLength(128)]
[Column("description")]
public string Description { get; set; }
[ForeignKey("Student")]
[Column("student_id")]
public Guid StudentId { get; set; }
[ForeignKey("Employer")]
[Column("employer_id")]
public Guid EmployerId { get; set; }
[ForeignKey("Customer")]
[Column("customer_id")]
public Guid CustomerId { get; set; }
public virtual Guid Student { get; set; }
public virtual Guid Employer { get; set; }
public virtual Guid Customer { get; set; }
}
E vedo la prossima istantanea di DbContext
:
modelBuilder.Entity("DataInterface.Models.Order", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnName("id");
b.Property<string>("Description")
.HasColumnName("description")
.HasMaxLength(128);
b.Property<Guid>("StudentId")
.HasColumnName("student_id");
b.Property<Guid>("EmployerId")
.HasColumnName("employer_id");
b.Property<Guid>("CustomerId")
.HasColumnName("customer_id");
b.HasKey("Id");
b.HasIndex("StudentId");
b.HasIndex("EmployerId");
b.HasIndex("CustomerId");
b.ToTable("order");
});
Come puoi vedere, tutto bene. Ma devo creare una chiave composita ed eliminare la chiave primaria. Facciamolo. Il mio nuovo codice dell'entità (senza chiave primaria Id
):
[Table("order")]
public class Order
{
[MaxLength(128)]
[Column("description")]
public string Description { get; set; }
[ForeignKey("Student")]
[Column("student_id")]
public Guid StudentId { get; set; }
[ForeignKey("Employer")]
[Column("employer_id")]
public Guid EmployerId { get; set; }
[ForeignKey("Customer")]
[Column("customer_id")]
public Guid CustomerId { get; set; }
public virtual Guid Student { get; set; }
public virtual Guid Employer { get; set; }
public virtual Guid Customer { get; set; }
}
Aggiungo un nuovo comportamento al metodo OnModelCreating
del mio contesto:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Order>()
.HasKey(x => new { x.StudentId, x.EmployerId, x.CustomerId });
}
Quando aggiungo una nuova migrazione, vedo che l'indice di StudentId
stato eliminato. E non capisco perché? La mia nuova istantanea di DbContext
:
modelBuilder.Entity("DataInterface.Models.Order", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnName("id");
b.Property<string>("Description")
.HasColumnName("description")
.HasMaxLength(128);
b.Property<Guid>("StudentId")
.HasColumnName("student_id");
b.Property<Guid>("EmployerId")
.HasColumnName("employer_id");
b.Property<Guid>("CustomerId")
.HasColumnName("customer_id");
b.HasKey("StudentId", "EmployerId", "CustomerId");
b.HasIndex("EmployerId");
b.HasIndex("CustomerId");
b.ToTable("order");
});
Perché uno dei tre indici è stato eliminato? Perché b.HasIndex("StudentId");
la linea è stata cancellata? Cosa c'è che non va?
Nota: non vedo questo problema con una chiave composita da due campi in altre tabelle.
La chiave primaria è imposta da un indice.
StudentId
è la prima colonna in quell'indice.
Non ha bisogno di un altro indice definito su di esso (un tale indice sarebbe quasi certamente anche inutile poiché è probabile che l'indice PK sia l'indice cluster per la tabella e gli indici non cluster contengono le colonne PK alle loro foglie)
Un indice aggiuntivo su StudentId
sarebbe ridondante. Poiché questa è la prima colonna della chiave primaria, una ricerca su StudentId
può semplicemente utilizzare il suo indice. Allo stesso modo una ricerca su StudentId
+ EmployerId
può fare lo stesso.
Aneddoticamente, questo non era il caso di EF Core e sono stati creati due indici. Il fatto che l'indice venga rimosso ora significa che questo comportamento è stato corretto / ottimizzato.