web-dev-qa-db-fra.com

Comment spécifier le nom de la clé primaire dans EF-Code-First

J'utilise Entity Framework Codefirst pour créer ma base de données. La clé primaire par défaut avec le nom de schéma dbo.pk_Jobs semble perturber l'accès 2007 lorsque je me connecte via ODBC. Si je modifie manuellement le nom, supprime le nom du schéma et renomme cette clé primaire en pk_jobs, Access peut maintenant lire la table. 

Puis-je spécifier que le nom de la clé primaire n'inclut pas le nom du schéma à l'aide d'API Fluent, d'attributs de données ou de toute autre méthode. 

public class ReportsContext : DbContext
{
    public DbSet<Job> Jobs { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Job>().ToTable("Jobs");
        modelBuilder.Entity<Job>().HasKey(j => j.uuid);

        base.OnModelCreating(modelBuilder);
    }
}
public class Job
{
    public Guid uuid{ get; set; }
    public int active{ get; set; }
}
25
tourdownunder

Si vous souhaitez spécifier le nom de la colonne et remplacer le nom de la propriété, vous pouvez essayer les solutions suivantes:

Utiliser des annotations

public class Job
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Column("CustomIdName")]
    public Guid uuid { get; set; }
    public int active { get; set; }
}

Utiliser le code d'abord

    protected override void OnModelCreating(DbModelBuilder mb)
    {
        base.OnModelCreating(mb);

        mb.Entity<Job>()
            .HasKey(i => i.uuid);
        mb.Entity<Job>()
          .Property(i => i.uuid)
          .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
          .HasColumnName("CustomIdName");
    }

Configuration de migration interne

public partial class ChangePrimaryKey : DbMigration
{
    public override void Up()
    {
        Sql(@"exec sp_rename 'SchemaName.TableName.IndexName', 'New_IndexName', 'INDEX'");
    }

    public override void Down()
    {
        Sql(@"exec sp_rename 'SchemaName.TableName.New_IndexName', 'Old_IndexName', 'INDEX'");
    }
}
52
cubski

Vous pouvez utiliser l'attribut Key pour spécifier les parties de la clé primaire. Donc, votre classe d'emploi pourrait être

public class Job
{
    [Key]
    public Guid uuid{ get; set; }
    public int active{ get; set; }
}

Les attributs d'annotation de données sont définis dans l'espace de noms System.ComponentModel.DataAnnotations

7
Chris Dunaway

Si je comprends bien, vous demandez comment changer le nom de la colonne de clé primaire utilisée par Entity Framework. L’ajout suivant à votre déclaration HasKey devrait s’occuper de cela:

modelBuilder.Entity<Job>().Property(j => j.uuid).HasColumnName("pk_Jobs")
1
Jeff Siver

(Ceci est un complément aux réponses/commentaires de @Jeff Sivers et @cubski.)

Autant que je sache, vous ne pouvez pas spécifier le nom de la PK avec l'attribut de données. Parfois, je dois me débarrasser de la partie dbo. du nom et ensuite utiliser une première migration de code modifiée manuellement pour changer le nom, comme ceci:

public partial class ChangeNameOnPKInCustomers : DbMigration
{
    private static string fromName = "PK_dbo.Customers";    // Name to change

    private static string toName = fromName.Replace("dbo.", "");

    public override void Up()
    {
        Sql($"exec sp_rename @objname=N'[dbo].[{fromName}]', @newname=N'{toName}'");
        // Now the PK name is "PK_Customers".
    }

    public override void Down()
    {
        Sql($"exec sp_rename @objname=N'[dbo].[{toName}]', @newname=N'{fromName}'");
        // Back to "PK_dbo.Customers".
    }
}
1
savehansson

Lorsque vous ajoutez une migration explicite à l'aide de Code First, vous obtenez un fichier .cs avec le nom de la migration, qui est une classe partielle avec une classe de base DbMigration. 

Pour votre contrainte de clé primaire, vous avez la fonction DropPrimaryKey ou AddPrimaryKey selon ce que vous essayez de faire. Mon problème était avec DropPrimaryKey car mon Db avait un nom différent pour la clé primaire.

Des surcharges sur ces deux fonctions prennent le nom de la PK afin que vous puissiez spécifier explicitement le nom de la PK. A bien fonctionné pour moi pour DropPrimaryKey avec un nom de PK explicite. L'argument étant l'objet anonymousArguments qui est par défaut null.

0