![](/img/trans.png)
[英]MetadataException [Unable to load the specified metadata resource]
[英]Unable to load the specified metadata resource Release vs Debug build
幾個小時以來,我一直在為 Entity Framework 中的一個特殊問題而撓頭。
以下問題不是重復的,因為他們的答案對我沒有幫助:
我有一個aspnet core
mvc 應用程序 ( v1.1
),它引用了一個.NET Framework 4.7
項目(數據訪問層),其中Entity Framework 6.1.3
作為 NuGet 包安裝。
我正在使用設計器,所以我有一個.edmx
文件。
我在運行時收到以下異常:
System.Data.Entity.Core.MetadataException: Unable to load the specified metadata resource.
at System.Data.Entity.Core.Metadata.Edm.MetadataArtifactLoaderCompositeResource.LoadResources(String assemblyName, String resourceName, ICollection`1 uriRegistry, MetadataArtifactAssemblyResolver resolver)
at System.Data.Entity.Core.Metadata.Edm.MetadataArtifactLoaderCompositeResource.CreateResourceLoader(String path, ExtensionCheck extensionCheck, String validExtension, ICollection`1 uriRegistry, MetadataArtifactAssemblyResolver resolver)
at System.Data.Entity.Core.Metadata.Edm.MetadataArtifactLoader.Create(String path, ExtensionCheck extensionCheck, String validExtension, ICollection`1 uriRegistry, MetadataArtifactAssemblyResolver resolver)
at System.Data.Entity.Core.Metadata.Edm.MetadataCache.SplitPaths(String paths)
at System.Data.Entity.Core.Common.Utils.Memoizer`2.<>c__DisplayClass2.<Evaluate>b__0()
at System.Data.Entity.Core.Common.Utils.Memoizer`2.Result.GetValue()
at System.Data.Entity.Core.Common.Utils.Memoizer`2.Evaluate(TArg arg)
at System.Data.Entity.Core.Metadata.Edm.MetadataCache.GetArtifactLoader(DbConnectionOptions effectiveConnectionOptions)
at System.Data.Entity.Core.Metadata.Edm.MetadataCache.GetMetadataWorkspace(DbConnectionOptions effectiveConnectionOptions)
at System.Data.Entity.Core.EntityClient.EntityConnection.GetMetadataWorkspace()
at System.Data.Entity.Core.Objects.ObjectContext.RetrieveMetadataWorkspaceFromConnection()
at System.Data.Entity.Core.Objects.ObjectContext..ctor(EntityConnection connection, Boolean isConnectionConstructor, ObjectQueryExecutionPlanFactory objectQueryExecutionPlanFactory, Translator translator, ColumnMapFactory columnMapFactory)
at System.Data.Entity.Internal.InternalConnection.CreateObjectContextFromConnectionModel()
at System.Data.Entity.Internal.LazyInternalConnection.CreateObjectContextFromConnectionModel()
at System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
at System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()
at System.Data.Entity.Internal.Linq.InternalSet`1.GetEnumerator()
at System.Data.Entity.Infrastructure.DbQuery`1.System.Collections.Generic.IEnumerable<TResult>.GetEnumerator()
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
我有以下連接字符串:
metadata=res://*/MyContext.csdl|res://*/MyContext.ssdl|res://*/MyContext.msl;provider=System.Data.SqlClient;provider connection string="data source=.;initial catalog=MyDatabase;integrated security=True;multipleactiveresultsets=True;App=EntityFramework"
問題是,在Debug
版本中運行時,應用程序運行沒有任何問題。 但是,在Release
版本中運行時,會拋出異常。 但是,如果我使用.edmx
文件禁用項目上的optimize code
,則不再拋出異常。
我什至查看了實體框架源代碼。 您可以從 Stacktrace 中看到,這個異常在第170
行拋出,因為loaders.Count == 0
。 我不明白為什么在Release
版本中不能從程序集中加載資源,而它在Debug
版本中工作。
編輯我剛剛安裝了 Reflector 的試用版來檢查組件。 因此,當查看使用 Debug 配置構建的.dll
文件時,我可以清楚地看到嵌入的 3 個資源文件。 但是,在使用 Release 配置構建的程序集中,奇怪的是缺少資源文件!
我找到了解決此問題的方法。
我的目標是一個帶有使用 EDMX 的遺留項目的 .net core 3.1 linux 容器。 首先在代碼中遷移整個 EDMX 將花費大量時間,因此我必須找到一個解決方案使其在 Azure 中工作。
問題是像dotnet publish
這樣的 dotnet cli 命令沒有嵌入 csdl、msl 或 ssdl 文件,請參閱問題 #8932 。 所以不要將它嵌入到輸出程序集中。 這在此線程中進行了部分解釋。
請注意,您需要打開 EDMX 文件(雙擊),因為單擊將顯示文件的屬性。
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Condition="'$(OS)' == 'Unix'" Command="echo *** cp -a $(ProjectDir)$(OutDir)* $(TargetDir)" />
<Exec Condition="'$(OS)' == 'Unix'" Command="cp -a $(ProjectDir)$(OutDir)* $(TargetDir)" />
<Exec Condition="'$(OS)' != 'Unix'" Command="echo *** copy /Y $(ProjectDir)$(OutDir)* $(TargetDir)" />
<Exec Condition="'$(OS)' != 'Unix'" Command="copy /Y $(ProjectDir)$(OutDir)* $(TargetDir)" />
</Target>
請注意,您必須調整復制命令路徑以匹配您的解決方案(例如,如果您的 EDMX 項目位於子項目中)。
從
connectionString="metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl;provider=System.Data.SqlClient;provider connection string=[...]"
至
connectionString="metadata=/app;provider=System.Data.SqlClient;provider connection string=[...]"
由於文件夾在發布/調試/發布時更改,我在我的應用程序中創建了這個小函數來更改連接字符串:
private string EntityConnectionString(string connectionString)
{
EntityConnectionStringBuilder csb = new EntityConnectionStringBuilder
{
ProviderConnectionString = connectionString,
Metadata = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)
};
csb.Provider = "System.Data.SqlClient";
return csb.ConnectionString;
}
只需將經典的非 EDMX 格式的連接字符串提供給函數的 connectionString 參數即可。 即:
data source=[...];initial catalog=EntityframeworkTest;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.