731 votes

MetadataException : Impossible de charger la ressource de métadonnées spécifiée

Tout d'un coup, je reçois un MetadataException lors de l'instanciation de mon ObjectContext classe. La chaîne de connexion dans App.Config semble correcte - elle n'a pas changé depuis la dernière fois qu'elle a fonctionné - et j'ai essayé de régénérer un nouveau modèle (fichier edmx) à partir de la base de données sous-jacente, sans changement.

Quelqu'un a une idée ?

Plus de détails : Je n'ai modifié aucune propriété, je n'ai pas changé le nom des assemblages de sortie, je n'ai pas essayé d'intégrer l'EDMX dans l'assemblage. J'ai simplement attendu 10 heures entre le moment où j'ai quitté le travail et mon retour. Et puis ça ne marchait plus.

J'ai essayé de recréer l'EDMX. J'ai essayé de recréer le projet. J'ai même essayé de recréer la base de données, à partir de zéro. Sans succès.

16 votes

Si une question sur un produit spécifique a été vue plus de 200 000 fois, cela signifie que le produit ne fonctionne pas comme les utilisateurs l'attendent. J'aimerais que Microsoft s'attaque à ce problème. Voici un lien pour leur faire des suggestions si vous avez le temps : visualstudio.uservoice.com/forums/121579-visual-studio .

1 votes

Mon problème a été résolu en remplaçant la chaîne de connexion copiée du projet db-layer.

0 votes

Je suis également confronté à ce problème, j'ai juste nettoyé et reconstruit la solution qui fonctionne bien.

884voto

Craig Stuntz Points 95965

Cela signifie que l'application est incapable de charger l'EDMX. Plusieurs facteurs peuvent être à l'origine de ce problème.

  • Vous avez peut-être changé la propriété MetadataArtifactProcessing du modèle en Copy to Output Directory.
  • La chaîne de connexion peut être erronée. Je sais que vous dites que vous ne l'avez pas modifiée, mais si vous avez changé d'autres choses (par exemple, le nom d'un assemblage), elle peut encore être fausse.
  • Il se peut que vous utilisiez une tâche post-compilation pour intégrer l'EDMX dans l'assemblage, ce qui ne fonctionne plus pour une raison quelconque.

En résumé, votre question n'est pas suffisamment détaillée pour que vous puissiez y répondre avec précision, mais j'espère que ces quelques idées vous mettront sur la bonne voie.

Mise à jour : J'ai écrit un article de blog avec des étapes plus complètes pour le dépannage .

72 votes

La chaîne de connexion, malgré mes efforts pour la comparer avec un utilitaire de comparaison de contenu la dernière fois, était mauvais.

17 votes

Pour moi aussi, c'était le branchement. Lorsque vous avez des tests d'intégration qui ont également besoin d'une connexion dans leur propre App.config, les choses peuvent se désynchroniser lorsque vous mettez à jour votre edmx.

0 votes

Oui, j'ai modifié les paramètres du MetadataArtifactProcessing et du post-compile etc. alors comment puis-je résoudre le problème ?

390voto

MicTech Points 6080

Ce petit changement permet de résoudre ce problème.

J'ai la solution avec 3 projets.

connectionString="metadata=res://*/Model.Project.csdl|res://*/Model.Project.ssdl|res://*/Model.Project.msl;

changer pour

connectionString="metadata=res://*/;

14 votes

Ça l'a réparé pour moi, mais qu'est-ce que ça veut dire ?

19 votes

@Lance : J'explique cela en détail dans cet article de blog

4 votes

@jocull : Non, cela ne fonctionnera pas dans de nombreux cas, et sera lent dans d'autres. Lisez mon article de blog pour comprendre pourquoi.

117voto

user276695 Points 944

Vous pouvez obtenir cette exception lorsque l'Edmx se trouve dans un projet et que vous l'utilisez à partir d'un autre.

La raison en est que Res://*/ est un uri qui pointe vers les ressources de l'assemblage CURRENT. Si l'Edm est défini dans un assemblage différent de celui du code qui l'utilise, res://*/ ne fonctionnera pas car la ressource est introuvable.

Au lieu de spécifier '*', vous devez fournir le nom complet de l'assemblage (y compris le jeton de clé publique). Par exemple

res://YourDataAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=abcdefabcedf/YourEdmxFileName.csdl|res://...

Une meilleure façon de construire des chaînes de connexion est d'utiliser EntityConnectionStringBuilder :

public static string GetSqlCeConnectionString(string fileName)
{
    var csBuilder = new EntityConnectionStringBuilder();

    csBuilder.Provider = "System.Data.SqlServerCe.3.5";
    csBuilder.ProviderConnectionString = string.Format("Data Source={0};", fileName);

    csBuilder.Metadata = string.Format("res://{0}/YourEdmxFileName.csdl|res://{0}/YourEdmxFileName.ssdl|res://{0}/YourEdmxFileName.msl", 
        typeof(YourObjectContextType).Assembly.FullName);

    return csBuilder.ToString();
}

public static string GetSqlConnectionString(string serverName, string databaseName)
{
    SqlConnectionStringBuilder providerCs = new SqlConnectionStringBuilder();

    providerCs.DataSource = serverName;
    providerCs.InitialCatalog = databaseName;
    providerCs.IntegratedSecurity = true;

    var csBuilder = new EntityConnectionStringBuilder();

    csBuilder.Provider = "System.Data.SqlClient";
    csBuilder.ProviderConnectionString = providerCs.ToString();

    csBuilder.Metadata = string.Format("res://{0}/YourEdmxFileName.csdl|res://{0}/YourEdmxFileName.ssdl|res://{0}/YourEdmxFileName.msl",
        typeof(YourObjectContextType).Assembly.FullName);

    return csBuilder.ToString();
}

Si vous rencontrez toujours l'exception, ouvrez l'assemblage dans Reflector et vérifiez les noms de vos fichiers .csdl, .ssdl et .msl. Si les ressources ont des noms différents de ceux spécifiés dans la valeur des métadonnées, cela ne fonctionnera pas.

8 votes

Veuillez considérer que "YourEdmxFileName" doit être le nom qualifié, par exemple "YourNamespace.YourEdmxFileName", si vous utilisez des espaces de noms dans votre assemblage. Cependant, vous devez supprimer la partie de l'espace de noms qui correspond au nom de votre assemblage.

5 votes

MSDN dit que le deuxième paragraphe est faux. "Lorsque vous utilisez un caractère générique (*), l'Entity Framework doit rechercher dans tous les assemblages les ressources portant le bon nom."

0 votes

Je suis presque sûr que l'espace de noms n'est pas pertinent, mais que le chemin du fichier intégré l'est. Ainsi, même si vous inspectez le fichier *.Designer.cs du fichier edmx associé et que vous remarquez que l'espace de nom de la classe générée automatiquement est MyCompany... peu importe, ce n'est pas ce que vous devez utiliser. Au lieu de cela, le chemin est le nom de l'assemblage, le nom du ou des dossiers de la solution et le nom du fichier. Par exemple : "metadata=res://*/EntityModels.<filename>.csdl|" + "res://*/EntityModels.<filename>.ssdl|" + "res://*/EntityModels.<filename>.msl ;"

72voto

Rick Arthur Points 884

J'ai eu une erreur similaire. J'avais recréé le projet (longue histoire), et tout repris de l'ancien projet. Je n'avais pas réalisé que mon modèle se trouvait auparavant dans un répertoire appelé "Model" et qu'il se trouvait maintenant dans un répertoire appelé "Models". Une fois que j'ai changé la connexion dans mon Web.Config de ceci :

<add name="RecipeManagerEntities" connectionString="metadata=res://*/Model.Recipe.csdl 

à ça :

<add name="RecipeManagerEntities" connectionString="metadata=res://*/Models.Recipe.csdl

Tout a fonctionné (changement Model a Models ). Notez que j'ai dû changer cela à trois endroits dans cette chaîne.

2 votes

J'ai déplacé mon modèle Entity Framework de Model à DAL. Mais ensuite, lorsque j'ai écrit un test (une semaine plus tard) dans le projet de test pour tester le predicatebuilder Linq. J'ai eu cette erreur. J'ai corrigé le App.config des projets de test avec ce qu'il semblait être dans le web.config du projet principal - comme vous l'avez dit à trois endroits. Votre réponse simple m'a donc mis sur la bonne voie.

8 votes

Y a-t-il une différence entre les deux ?

2 votes

@ErwinRooijakkers Modèle vs ModèleS

30voto

leqid Points 451

Et un moyen rapide de vérifier le nom du modèle sans Reflector.... chercher le répertoire

...obj/{config output}/edmxResourcesToEmbed

et vérifiez que les fichiers de ressources .csdl, .msl et .ssdl s'y trouvent. S'ils sont dans un sous-répertoire, le nom du sous-répertoire doit être ajouté au nom du modèle.

Par exemple, mes trois fichiers ressources sont dans un sous-répertoire Données donc ma chaîne de connexion devait être

métadonnées=res://*/ Données .MyModel.csdl|res://*/ Données .MyModel.ssdl|res://*/ Données .MonModèle.msl ;

(versus metadata=res://*/MyModel.csdl|res://*/MyModel.ssdl|res://*/MyModel.msl ;).

0 votes

C'était EXACTEMENT mon problème. J'ai perdu plusieurs heures là-dessus. Merci beaucoup pour cette explication facile

0 votes

Excellente réponse, qui explique en fait comment trouver ce qu'est votre corde. Elle montre également que les sous-dossiers sont délimités par '.' et non par '\' ou '/'.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X