web-dev-qa-db-fra.com

Utilisez ColumnAttribute ou la méthode HasKey pour spécifier un ordre pour les clés primaires composites

J'essaie d'utiliser la clé primaire composite sur 2 objets avec une relation parent-enfant. Chaque fois que j'essaie de créer une nouvelle migration, j'obtiens une erreur:

Impossible de déterminer l'ordre des clés primaires composites pour le type 'Models.UserProjectRole'. Utilisez ColumnAttribute ou la méthode HasKey pour spécifier un ordre pour les clés primaires composites.

Comme l'indique l'erreur, j'ajoute l'annotation Column (Order = X) mais l'erreur est toujours là et ne disparaît pas, à moins que je ne laisse qu'un seul champ avec l'annotation clé. Voici mon objet qu'il déclenche:

public class UserProjectRole
{
    [Key, Column(Order = 0),DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid UserProjectRoleID { get; set; }

    [Key, Column (Order = 1)]
    public Guid ProjectID { get; set; }

    [ForeignKey("ProjectID")]
    public Project Project { get; set; }

    public Guid AppUserGuid { get; set; }

    // followed by a number of unrelated String fields.
 }

Voici la classe Project:

public class Project: Base
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid ProjectID { get; set; }

    public virtual ICollection<UserProjectRole> UserRoles { get; set; }

    // followed by a number of unrelated String fields.

}

Voici une partie de mon DBContext:

public class SiteContext : DbContext
{

    public DbSet<Project> Projects { get; set; }

    public DbSet<UserProjectRole> UserProjectRoles { get; set; }
}

Je suis dans VisualStudio 2012 avec EF 4.3.1

Je me suis cogné la tête contre cela depuis un moment maintenant et tous les forums et SO réponses suggèrent d'ajouter l'annotation de l'ordre des colonnes que j'ai déjà. Suis-je en train de manquer quelque chose d'évident ?? ?

Merci d'avoir lu jusqu'ici -)

31
trailmax

Il a fallu beaucoup de manipulations et de tests sur différentes choses. J'étais complètement désemparé jusqu'à ce que je décide de faire un nouveau projet Vanilla avec la structure de données similaire à partir de zéro. Et lorsque j'ai installé EntityFramework à partir de NuGet, un message m'a été montré:

Problèmes connus avec Entity Framework 4.x et .NET Framework 4.5

Entity Framework 4.1 à 4.3 comprenait des annotations de données supplémentaires dans l'espace de noms System.ComponentModel.DataAnnotations dans l'assembly EntityFramework. Dans .NET 4.5, ces annotations ont été déplacées pour faire partie du .NET Framework dans l'espace de noms System.ComponentModel.DataAnnotations.Schema de l'assembly System.ComponentModel.DataAnnotations.dll. Si vous utilisez EF 4.x et ciblez .NET 4.5, cela entraîne deux annotations de données avec le même nom dans différents assemblys. Étant donné que les annotations dans le .NET Framework se trouvent dans un espace de noms différent, nous n'avons pas pu utiliser le transfert de type pour éviter ce conflit.

Il est possible d'utiliser EF 4.x sur .NET 4.5 mais nous vous recommandons d'utiliser la dernière version préliminaire d'EF 5. Si vous n'utilisez pas les annotations de données affectées, cela n'a aucun impact sur votre code. Si vous utilisez les annotations de données dans un projet C #, vous pouvez utiliser le modificateur extern pour vous assurer que votre code utilise les annotations de EntityFramework.dll ( http://msdn.Microsoft.com/en-us/library/e59b22c5 (v = VS.80) .aspx ). Si vous utilisez les nouvelles annotations de l'assembly System.ComponentModel.DataAnnotations.dll dans .NET 4.5, elles ne seront pas traitées par Code First.

Les annotations affectées sont:

  • Colonne
  • ComplexType
  • DatabaseGenerated
  • DatabaseGeneratedOption
  • Clé étrangère
  • InverseProperty
  • Longueur maximale
  • Longueur minimale
  • NotMapped
  • Table

À ce stade, j'ai réalisé que mon projet de données avait été fraîchement créé dans VS2012 et ciblait par défaut .Net 4.5 et que le reste de mon projet dans les solutions avait migré de VS2010 et ciblé .Net 4.0. J'ai donc mis à jour tous les projets pour cibler .Net 4.5 et obtenu la pré-version d'EntityFramework 5.0.

Assurez-vous de mettre à jour vos projets en premier vers Net4.5, après cela, mettez à jour EF vers 5.0, sinon cela vous détestera pour toujours et de nombreux lapins mourront.

Ce screencast est un excellent démarreur pour la mise à jour vers EF5.0

À ce stade, mon erreur avait disparu, mais j'en obtenais un autre. Je n'ai pas pu ajouter la migration car il n'a pas pu trouver la configuration de la migration, même si j'avais configuré la configuration quelques secondes avant. Cela a de nouveau pris beaucoup de temps avec NuGet, en désinstallant les packages de réinstallation d'annonces. Ensuite, j'ai vu dans packages.config des lignes comme ceci:

package id="EntityFramework" version="5.0.0-rc" targetFramework="net40" 

J'ai changé targetFramework en "net45" et maintenant j'obtiens le comportement attendu des migrations. Je suppose qu'il y aurait un meilleur moyen d'obtenir la cible nuget .Net 4.5 avec des packages, mais c'est ce qui a fonctionné pour moi.

J'espère que cela sauvera quelqu'un se cognant la tête contre un mur.

16
trailmax
    public class UserProjectRole
    {
        [Key, Column (Order = 0)]
        public Guid UserProjectRoleID { get; set; }

    [Key, Column (Order = 1)]
    [ForeignKey("Project")]
    public Guid ProjectID { get; set; }

    [Required]
    public Project Project { get; set; }

    public Guid AppUserGuid { get; set; }

    // followed by a number of unrelated String fields.
 }

public class Project: Base
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid ProjectID { get; set; }

    public virtual ICollection<UserProjectRole> UserRoles { get; set; }

    // followed by a number of unrelated String fields.

}

    public class SiteContext : DbContext
{

    public DbSet<Project> Projects { get; set; }

    public DbSet<UserProjectRole> UserProjectRoles { get; set; }
}

Essayez ceci, en particulier avec le [Required] Au-dessus du public Project Project {get; set;}.

Si cela ne fonctionne pas, réessayez et supprimez la [Key, Column (Order = 1)] au-dessus de la [ForeignKey("ProjectID")]

9
Abed G.

Voici le correctif pour ceux avec des lapins morts (ayant mis à jour vers EF 5.0 avant de mettre à jour vers .Net 4.5):

Dans les fichiers csproj, modifiez

<Reference Include="EntityFramework, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
  <SpecificVersion>False</SpecificVersion>
  <HintPath>..\packages\EntityFramework.5.0.0\lib\net40\EntityFramework.dll</HintPath>
</Reference>

À

<Reference Include="EntityFramework">
  <HintPath>..\packages\EntityFramework.5.0.0\lib\net45\EntityFramework.dll</HintPath>
</Reference>

Assez évident quand vous le savez ....

6

J'ai pu arriver à la même solution en utilisant

PM> Install-Package EntityFramework -Pre

http://weblogs.asp.net/scottgu/archive/2012/12/11/entity-framework-6-alpha2-now-available.aspx

2
James Fleming