2009-07-02 12 views
61

Questo codice:MetadataException quando si utilizza Entity Framework Entity Connection

using (EntityConnection conn = new EntityConnection("name=ELSCommonEntities")) 
{ 
    conn.Open(); 
} 

mi dà il seguente errore:

Test method ELS.Service.Business.IntegrationTest.Base.ServiceBaseIntegrationTest.StartLoggingTestMethod threw exception: System.Data.MetadataException: Unable to load the specified metadata resource.. 

Con la seguente analisi dello stack:

System.Data.Metadata.Edm.MetadataArtifactLoaderCompositeResource.LoadResources(String assemblyName, String resourceName, ICollection`1 uriRegistry, MetadataArtifactAssemblyResolver resolver) 
System.Data.Metadata.Edm.MetadataArtifactLoaderCompositeResource.CreateResourceLoader(String path, ExtensionCheck extensionCheck, String validExtension, ICollection`1 uriRegistry, MetadataArtifactAssemblyResolver resolver) 
System.Data.Metadata.Edm.MetadataArtifactLoader.Create(String path, ExtensionCheck extensionCheck, String validExtension, ICollection`1 uriRegistry, MetadataArtifactAssemblyResolver resolver) 
System.Data.EntityClient.EntityConnection.SplitPaths(String paths) 
System.Data.EntityClient.EntityConnection.GetMetadataWorkspace(Boolean initializeAllCollections) 
System.Data.EntityClient.EntityConnection.InitializeMetadata(DbConnection newConnection, DbConnection originalConnection, Boolean closeOriginalConnectionOnFailure) 
System.Data.EntityClient.EntityConnection.Open() 
ELS.Service.Business.Base.ServiceBase.StartLogging(String userWindowsLogon) in C:\C-TOM\ELS-RELEASE1\ELS.Service.Business\Base\ServiceBase.cs: line 98 
ELS.Service.Business.IntegrationTest.Base.ServiceBaseIntegrationTest.StartLoggingTestMethod() in C:\C-TOM\ELS-RELEASE1\ELS.Service.Business.IntegrationTest\Base\ServiceBaseIntegrationTest.cs: line 65 

Tuttavia, questo codice che utilizza la stessa stringa di connessione:

using (ELSCommonEntities db = new ELSCommonEntities()) 
{ 
    var res = from c in db.Logging 
       select c; 

    int i = res.Count(); 
} 

Non dà un errore.

La stringa di connessione è:

<add name="ELSCommonEntities" connectionString="metadata=res://*/Common.CommonModel.csdl|res://*/Common.CommonModel.ssdl|res://*/Common.CommonModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=localhost;Initial Catalog=els5_demo;Integrated Security=True;MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" /> 

ho anche aperto la dll nel riflettore e metadati sembra ok.

+4

Si prega, per favore, di postare sempre l'eccezione completa, inclusa la traccia dello stack e le eccezioni interne. Pubblica i risultati di ex.ToString(). –

+3

Spero non ti dispiaccia. Ho modificato la tua domanda per correggere il formato. Dovresti indentare con quattro spazi per formattare come codice. Altrimenti, selezionare il codice e premere il pulsante con 10101. –

+0

Grazie per il suggerimento –

risposta

105

Trovato il problema.

La stringa di metadati di serie si presenta così:

metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl 

E questo funziona bene nella maggior parte dei casi. Tuttavia, in alcuni (compreso il mio) Entity Framework si confondono e non sa che dll di guardare in conseguenza, modificare la stringa metadati:.

metadata=res://nameOfDll/Model.csdl|res://nameOfDll/Model.ssdl|res://nameOfDll/Model.msl 

E funzionerà. E 'stato questo link che mi ha fatto sulla strada giusta:

http://itstu.blogspot.com/2008/07/to-load-specified-metadata-resource.html

Anche se ho avuto il problema oposite, non ha funzionato nella prova di unità, ma ha lavorato in servizio.

+4

"Alcuni casi" si verificano quando si ha più di un file edmx con lo stesso nome (ad esempio Modello1). – alpav

+1

Il mio "caso" era con un solo file .edmx nella soluzione. Non ho idea di cosa sia successo, ma è stato orribile. ;) – jfar

+3

Il link che mi hai dato mi ha portato alla risposta, quindi stai ricevendo la mia revoca! Ho combattuto con questo per mezza giornata. Ho provato res: // NameOfDLL/... ma senza successo. Tuttavia, ho finalmente funzionato con res: // NameOfAssembly/... In questo caso, erano lo stesso nome, tranne che il nome dell'assembly non aveva .dll alla fine. –

0

Come ha risposto Shiraz Bhaiji, il metadata = res: ///Model.csdl | res: ///Model.ssdl | res: //*/Model.msl era il caso. Tuttavia ho ancora avuto problemi con la costruzione della stringa corretta in base alla localizzazione del mio modello, agli spazi dei nomi e al nome del gruppo. La soluzione molto semplice è stata quella di rinominare il file .edmx in Visual Studio (dopo averlo rinominato e tornare al nome originale), che ha attivato l'aggiornamento automatico della stringa nel mio Web.config

43

Ho avuto lo stesso messaggio di errore e il problema era anche la parte dei metadati della stringa di connessione, ma dovevo scavare un po 'più a fondo per risolverlo e volevo condividere questo piccolo nugget:

La stringa di metadati è composta da tre sezioni che sembrano tutte questo:

res:// 
     (assembly)/ 
     (model name).(ext) 

Dove ext è "CSDL", "ss dl "e" msl ".

Per la maggior parte delle persone, l'assemblaggio può probabilmente essere "*", il che sembra indicare che tutti gli assembly caricati verranno cercati (non ho eseguito una grande quantità di test su questo). Questa parte non era un problema per me, quindi non posso commentare se è necessario il nome dell'assembly o il nome del file (cioè, con o senza ".dll"), anche se ho visto entrambi suggerito.

Il modello di nome parte dovrebbe essere il nome e namespace del file .edmx, relativo alla vostra assemblea. Quindi, se si dispone di un My.DataAccess montaggio e si crea DataModels.edmx in una cartella modelle, il suo nome completo è My.DataAccess.Models.DataModels. In questo caso, avresti "Models.DataModels. (Ext)" nei tuoi metadati.

Se si sposta o si rinomina il file .edmx, è necessario aggiornare manualmente la stringa di metadati (nella mia esperienza) e ricordarsi di modificare lo spazio dei nomi relativo farà risparmiare alcuni grattacapi.

+6

GRAZIE! Ci sono 100 risposte per questo disponibili su Internet, ma questa è l'addendum più utile per ognuna di esse. Un chiaro esempio: In 'DalProject.dll' si ha una cartella' Client' che contiene il file 'Client.edmx'. Quindi si sostituisce '// */Client. (Csdl/ssdl/msl)' con '//DalProject/Client.Client. (Csdl/ssdl/msl)' – Maverick

+0

Sembra "My.DataAccess". non è richiesto; solo la parte "Models.DataModels" (forse funziona in relazione a ogni spazio dei nomi di root dell'assembly cercato). –

14

Esistono diverse possibilità di cattura. Penso che l'errore più comune è in questa parte della stringa di connessione:

res://xxx/yyy.csdl|res://xxx/yyy.ssdl|res://xxx/yyy.msl;

Questa non è una magia. Una volta capito cosa significa, otterrai la stringa di connessione giusta.

Prima la parte xxx. Questo è nient'altro che un nome di assembly in cui hai definito il tuo contesto EF clas. Di solito sarebbe qualcosa come MyProject.Data. Il valore predefinito è * che rappresenta tutti gli assiemi caricati. È sempre meglio specificare un nome particolare dell'assembly.

Ora la yyy parte. Questo è un nome di risorsa nell'assemblaggio xxx. In genere si tratta di un percorso relativo al file .edmx con punti anziché barre. Per esempio. Modelli/Catalogo - Modelli.Catalog Il modo più semplice per ottenere la stringa corretta per l'applicazione è creare l'assembly xxx. Quindi apri il file di assembly assembly in un editor di testo (preferisco il visualizzatore predefinito di Total Commander) e cerca ".csdl". Di solito non ci sarà più di 1 occorrenza di quella stringa.

la stringa di connessione EF finale può apparire come segue:

res://MyProject.Data/Models.Catalog.DataContext.csdl|res://MyProject.Data/Models.Catalog.DataContext.ssdl|res://MyProject.Data/Models.Catalog.DataContext.msl;

+2

Ricerca nella DLL. Ultra Top Tip. Grazie :) – uniquelau

0

Ho avuto lo stesso problema con tre progetti in un'unica soluzione e tutti i suggerimenti non ha funzionato fino a quando ho fatto un punto di riferimento nel file di riferimento del progetto del sito web al progetto in cui si trova il file edmx.

0

Ho spostato il mio Database First DataModel in un progetto diverso a metà dello sviluppo. Povera pianificazione (o mancanza di) da parte mia.

Inizialmente avevo una soluzione con un progetto. Quindi ho aggiunto un altro progetto alla soluzione e ricreato il mio Database First DataModel dalla Dataase del server Sql.

Per risolvere il problema - MetadataException quando si utilizza Entity Framework Entity Connection. Ho copiato il mio ConnectionString dal nuovo progetto Web.Config al progetto originale Web.Config.Tuttavia, ciò si è verificato dopo aver aggiornato tutti i riferimenti nel progetto originale al nuovo progetto DataModel.

0

Potrebbe trattarsi semplicemente di un errore di stringa di connessione, risolto con il processo precedente, ma se si stanno utilizzando le DLL in più progetti, accertarsi che la stringa di connessione sia denominata correttamente risolverà sicuramente l'errore.

0

Ho riscontrato questo problema quando spostavo il mio primo modello di database da un progetto a un altro.

ho semplicemente fatto il seguente:

  1. eliminato lo stringhe di connessione nel app.config o web.config
  2. eliminata la 'Model.edmx'
  3. Re-ha aggiunto il modello per il progetto.