Entity Framework – Nom de colonne non valide ‘* _ID “

Je l’ai réduit à un problème entre Code First et Database first EF, mais je ne suis pas sûr de savoir comment le résoudre. Je vais essayer d’être aussi clair que possible, mais honnêtement, je manque une partie de la compréhension ici. Ceci est Entity Framework 4.4

J’ai hérité d’un projet où Entity Framework était utilisé, mais beaucoup de fichiers réels ont été supprimés sans réel moyen de revenir en arrière. J’ai rajouté EF (Database first) et répliqué une configuration T4 autour de laquelle le projet a été construit. Il a généré des versions de code de tous les modèles de firebase database et un fichier de code DBContext.

Si ma chaîne de connexion ressemble à une chaîne de connexion .NET “normale”, j’obtiens une erreur concernant une colonne non valide. Nom “ProcessState_ID” n’existe pas. ProcessState_ID n’est pas dans la base de code, il ne se trouve pas dans le fichier EDMX ou quoi que ce soit. Cela semble être une conversion EF automatique dans la requête.

Lorsque je fais correspondre la chaîne de connexion au modèle Entity Framework, cela fonctionne correctement.

Maintenant, en essayant de faire correspondre le code précédent avec Entity Framework, j’aimerais conserver la chaîne de connexion .NET “normale”.

J’ai donc deux questions ici: 1. Quelle est la bonne façon de passer d’une chaîne de connexion normale à une chaîne de connexion EF dans le code? 2. Y a-t-il un autre correctif que je ne vois pas pour arrêter l’erreur de nom de colonne non valide?

Vérifiez si vous avez des ICollections.

Ce que j’ai compris, c’est que lorsque vous avez une ICollection qui fait référence à une table et qu’il n’y a pas de colonne à comprendre, cela en crée une pour essayer d’établir la connexion entre les tables. Cela se produit spécifiquement avec ICollection et m’a poussé à me battre.

Ceci est une entrée tardive pour ceux (comme moi) qui n’ont pas compris immédiatement les 2 autres réponses.

Alors…

EF essaie de mapper le nom EXPECTED du CLÉ-RÉFÉRENCE DES TABLEAUX PARENTS … et depuis … le nom FOREIGN KEY a été “changé ou raccourci” dans la relation CHILD TABLE des bases de données … vous obtiendrez le message ci-dessus.

(ce correctif peut différer entre les versions de EF)

Pour moi le correctif était:
AJOUTER l’atsortingbut “ForeignKey” au modèle

 public partial class Tour { public Guid Id { get; set; } public Guid CategoryId { get; set; } [Required] [SsortingngLength(200)] public ssortingng Name { get; set; } [SsortingngLength(500)] public ssortingng Description { get; set; } [SsortingngLength(50)] public ssortingng ShortName { get; set; } [SsortingngLength(500)] public ssortingng TourUrl { get; set; } [SsortingngLength(500)] public ssortingng ThumbnailUrl { get; set; } public bool IsActive { get; set; } [Required] [SsortingngLength(720)] public ssortingng UpdatedBy { get; set; } [ForeignKey("CategoryId")] public virtual TourCategory TourCategory { get; set; } } 

Holy cow – après plusieurs heures d’essai, j’ai finalement compris.

Je fais d’abord la firebase database EF6 et je m’interrogeais sur l’erreur “étendue de la colonne inconnue” – elle générait le nom de la colonne de soulignement du nom de la table pour une raison quelconque et essayait de trouver une colonne inexistante.

Dans mon cas, une de mes tables avait deux références de clé étrangère à la même clé primaire dans une autre table – quelque chose comme ceci:

 Animals Owners ======= ====== AnimalID (PK) Pet1ID <- FK to AnimalID Pet2ID <- also FK to AnimalID 

EF générait un nom de colonne étrange comme Owners_AnimalID1 et Owners_AnimalID2 , puis procédait à sa propre rupture.

L'astuce ici est que ces clés étrangères déroutantes doivent être enregistrées avec EF en utilisant l'API Fluent!

Dans votre contexte de firebase database principal, remplacez la méthode OnModelCreating et modifiez la configuration de l'entité. De préférence, vous aurez un fichier séparé qui étend la classe EntityConfiguration , mais vous pouvez le faire en ligne.

De toute façon, vous devez append quelque chose comme ceci:

 public class OwnerConfiguration : EntityTypeConfiguration { public OwnerConfiguration() { HasRequired(x => x.Animals) .WithMany(x => x.Owners) // Or, just .WithMany() .HasForeignKey(x => x.Pet1ID); } } 

Et avec cela, EF va (peut-être) commencer à travailler comme prévu. Boom.

En outre, vous obtiendrez la même erreur si vous utilisez ce qui précède avec une colonne .HasOptional() - utilisez simplement .HasOptional() au lieu de .HasRequired() .


Voici le lien qui m'a mis sur la butte:

https://social.msdn.microsoft.com/Forums/en-US/862abdae-b63f-45f5-8a6c-0bdd6eeabfdb/getting-sqlexception-invalid-column-name-userid-from-ef4-codeonly?forum=adonetefx

Et puis, l'API Fluent aide, en particulier les exemples de clés étrangères:

http://msdn.microsoft.com/en-us/data/jj591620.aspx

Vous pouvez également placer les configurations à l'autre extrémité de la clé, comme décrit ici:

http://www.entityframeworktutorial.net/code-first/configure-one-to-many-relationship-in-code-first.aspx .

Il y a quelques nouveaux problèmes sur lesquels je me heurte maintenant, mais c'était la grande lacune conceptuelle qui manquait. J'espère que cela aide!

Hypothèses:

  • Table
  • OtherTable
  • OtherTable_ID

Maintenant, choisissez l’une de ces manières:


UNE)

Supprimer ICollection

Si vous rencontrez des erreurs liées à OtherTable_ID lorsque vous récupérez Table , accédez au modèle OtherTable et assurez-vous de ne pas avoir de ICollection

. Sans une relation définie, le framework supposera automatiquement que vous devez avoir un FK vers OtherTable et créer ces propriétés supplémentaires dans le SQL généré.

Tous les crédits de cette réponse appartiennent à @LUKE. La réponse ci-dessus est son commentaire sous la réponse de @drewid. Je pense que son commentaire est si clair que je l’ai réécrit en réponse.


B)

  • Ajouter OtherTableId à la Table

et

  • Définir OtherTableId dans la Table dans la firebase database

Dans mon cas, je définissais à tort une clé primaire composée de deux clés étrangères comme ceci:

 HasKey(x => x.FooId); HasKey(x => x.BarId); HasRequired(x => x.Foo) .WithMany(y => y.Foos); HasRequired(x => x.Bar); 

L’erreur que j’obtenais était “nom de colonne non valide Bar_ID”.

La spécification de la clé primaire composite a correctement résolu le problème:

 HasKey(x => new { x.FooId, x.BarId }); ... 

J’ai aussi eu ce problème et il semble y avoir quelques causes différentes. Pour moi, c’était une propriété id définie par erreur comme int au lieu de long dans la classe parent qui contenait un object de navigation. Le champ id de la firebase database a été défini comme bigint, ce qui correspond à long en C #. Cela n’a pas provoqué d’erreur de compilation, mais a provoqué la même erreur d’exécution que l’OP obtenu:

 // Domain model parent object public class WidgetConfig { public WidgetConfig(long id, int stateId, long? widgetId) { Id = id; StateId = stateId; WidgetId = widgetId; } private WidgetConfig() { } public long Id { get; set; } public int StateId { get; set; } // Ensure this type is correct public long? WidgetId { get; set; } public virtual Widget Widget { get; set; } } // Domain model object public class Widget { public Widget(long id, ssortingng name, ssortingng description) { Id = id; Name = name; Description = description; } private Widget() { } public long Id { get; set; } public ssortingng Name { get; set; } public ssortingng Description { get; set; } } // EF mapping public class WidgetConfigMap : EntityTypeConfiguration { public WidgetConfigMap() { HasKey(x => x.Id); ToTable(nameof(WidgetConfig)); Property(x => x.Id).HasColumnName(nameof(WidgetConfig.Id)).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).IsRequired(); Property(x => x.StateId).HasColumnName(nameof(WidgetConfig.StateId)); Property(x => x.WidgetId).HasColumnName(nameof(WidgetConfig.WidgetId)); } } // Service public class WidgetsService : ServiceBase, IWidgetsService { private IWidgetsRepository _repository; public WidgetsService(IWidgetsRepository repository) { _repository = repository; } public List ListWithDetails() { var list = _repository.ListWithDetails(); return new WidgetConfigMapping().ConvertModelListToDtoList(list).ToList(); } } // Repository public class WidgetsRepository: BaseRepository, IWidgetsRepository { public WidgetsRepository(Context context) : base(context, id => widget => widget.Id == id) { } public IEnumerable ListWithDetails() { var widgets = Query .Include(x => x.State) .Include(x => x.Widget); return widgets; } } 

Pour moi, le problème est que la table a été mappée dans mon application deux fois – une fois via Code First, une fois via Database First.

Supprimer l’un ou l’autre résout le problème dans mon cas.

Si vous avez plusieurs références de clé étrangère à la même table, vous pouvez utiliser InverseProperty

Quelque chose comme ça-

 [InverseProperty("MyID1")] public virtual ICollection set1 { get; set; } [InverseProperty("MyID2")] public virtual ICollection set2 { get; set; } 

Pour moi (en utilisant Visual Studio 2017 et le premier modèle de firebase database sous Entity Framework 6.1.3), le problème a disparu après le redémarrage de Visual Studio et Rebuilding.