Внезапно я продолжаю получать MetadataException
при создании созданного класса ObjectContext
. Строка подключения в App.Config выглядит корректно - не изменилась с тех пор, как она работала, и я попытался восстановить новую модель (edmx файл) из базовой базы данных без изменений.
У кого-нибудь есть идеи?
Дополнительная информация: я не изменил никаких свойств, я не изменил имя каких-либо выходных сборок, я не пытался встраивать EDMX в сборку. Я просто ждал 10 часов от работы, пока не вернулся. И тогда он больше не работал.
Я пробовал воссоздать EDMX. Я пробовал воссоздать проект. Я даже пытался воссоздать базу данных с нуля. Не повезло, что бы ни случилось.
Это означает, что приложение не может загрузить EDMX. Есть несколько вещей, которые могут вызвать это.
Короче говоря, в вашем вопросе недостаточно подробностей, чтобы дать точный ответ, но, надеюсь, эти идеи помогут вам в правильном направлении.
Обновление: я написал сообщение в блоге с более полными шагами для устранения проблем.
Это небольшое изменение помогает решить эту проблему.
У меня есть решение с 3 проектами.
connectionString="metadata=res://*/Model.Project.csdl|res://*/Model.Project.ssdl|res://*/Model.Project.msl;
измените на
connectionString="metadata=res://*/;
Вы можете получить это исключение, когда Edmx находится в одном проекте, и вы используете его из другого.
Причиной является Res://*/
- это uri, который указывает ресурсы в сборке CURRENT. Если Edm определен в другой сборке из кода, который его использует, res://*/не будет работать, потому что ресурс не может быть найден.
Вместо указания "*" вам нужно указать полное имя сборки (включая токен открытого ключа). Например:
res://YourDataAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=abcdefabcedf/YourEdmxFileName.csdl|res://...
Лучший способ построения строк соединения - с 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();
}
Если вы все еще сталкиваетесь с этим исключением, откройте сборку в отражателе и проверьте имена файлов для файлов .csdl,.ssdl и .msl. Когда ресурсы имеют разные имена для тех, которые указаны в значении метаданных, он не будет работать.
У меня была аналогичная ошибка. Я воссоздал проект (длинный рассказ) и вытащил все из старого проекта. Я не понял, что моя модель раньше находилась в каталоге под названием "Модель" и теперь находилась в каталоге под названием "Модели". Как только я изменил соединение в своем Web.Config с помощью этого:
<add name="RecipeManagerEntities" connectionString="metadata=res://*/Model.Recipe.csdl
:
<add name="RecipeManagerEntities" connectionString="metadata=res://*/Models.Recipe.csdl
Все сработало (изменено Model
на Models
). Обратите внимание, что мне пришлось изменить эти три места в этой строке.
И быстрый способ проверить имя модели без Reflector.... искать каталог
... obj/{config output}/edmxResourcesToEmbed
и проверьте, есть ли файлы ресурсов .csdl,.msl и .ssdl. Если они находятся в подкаталоге, имя подкаталога должно быть добавлено к имени модели.
Например, мои три файла ресурсов находятся в подкаталоге Данные, поэтому моя строка подключения должна быть
метаданных = Рез://*/ Данные.MyModel.csdl | разрешение://*/ Данные.MyModel.ssdl | разрешение://*/ Данные.MyModel.msl;
(по сравнению с метаданными = res://*/MyModel.csdl | res://*/MyModel.ssdl | res://*/MyModel.msl;).
У меня также была эта проблема, и это произошло потому, что connectionstring в моем web.config немного отличалась от той, что находится в app.config сборки, где находится мой EDMX. Не знаю, почему это изменилось, но вот две разные версии.
App.config:
<add name="SCMSEntities" connectionString="metadata=res://*/Model.SMCSModel.csdl|res://*/Model.SMCSModel.ssdl|res://*/Model.SMCSModel.msl;provider=System.Data.SqlClient;provider connection string="data source=SANDIEGO\sql2008;initial catalog=SCMS;integrated security=True;multipleactiveresultsets=True;application name=EntityFramework"" providerName="System.Data.EntityClient" />
Web.config:
<add name="SCMSEntities" connectionString="metadata=res://*/Model.SCMSModel.csdl|res://*/Model.SCMSModel.ssdl|res://*/Model.SCMSModel.msl;provider=System.Data.SqlClient;provider connection string="data source=SANDIEGO\sql2008;initial catalog=SCMS;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
Исправлено просто копирование строки app.config(обратите внимание на небольшую разницу в конце - вместо "App=EntityFramework
" он захотел "application name=EntityFramework
" ) в web.config, и проблема была решена.:)
The .NET Framework data provider for SQL Server (SqlClient) supports many keywords from older APIs, but is generally more flexible and accepts synonyms for many of the common connection string keywords.
Строки подключения Entity Framework не обладают такой гибкостью, поэтому вы должны использовать только те ключевые слова, которые ожидаются.
Это случилось со мной, когда я случайно переключил действие сборки файла edmx (появляется в разделе "Свойства в среде IDE" ) с "EntityDeploy" на "None". EntityDeploy - это то, что заполняет метаданные для вас: см. http://msdn.microsoft.com/en-us/library/cc982037.aspx
Я только что провел 30 минут с этим. Я переименовал объект объектов, переименовал запись в файле конфигурации, но там еще... вам также нужно изменить ссылку на csdl
очень легко пропустить - если вы переименовываете, убедитесь, что вы получили все....
Я потратил целый день на эту ошибку
если вы работаете с n-tear architecture
или вы попытались separate Models
, сгенерированный формой EDMX
с DataAccessLayer, на DomainModelLayer
возможно, вы получите эту ошибку
webconfig (UILayer)
и appconfig (DataAccessLayer)
одинаковаВо-вторых, очень важно connection string
connectionString="metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl;provid.....
что является проблемой
откуда я получил Model
или что-то .csdl в моей строке соединения, где они
вот я наше решение посмотрю на картинку
надеюсь, что вам поможет
В моем случае он решается путем изменения свойств файла edmx.
это решило проблему для меня. Проблема в том, что, когда контейнер пытается найти метаданные, он не может найти его. поэтому просто сделайте это в той же сборке. это решение не будет работать, если у вас есть файлы edmx в другой сборке
У меня была та же проблема. Я заглянул в свою обработанную dll с отражателем и увидел, что имя ресурса было неправильным. Я переименовал, и теперь это выглядит нормально.
Я смог разрешить это в Visual Studio 2010, VB.net(ASP.NET) 4.0.
Во время мастера модели сущностей вы сможете увидеть строку соединения с сущностью. Оттуда вы можете скопировать и вставить в строку подключения.
Единственное, чего мне не хватало, это "App_Code". в строке соединений.
entityBuilder.Metadata = "res://*/App_Code.Model.csdl|res://*/App_Code.Model.ssdl|res://*/App_Code.Model.msl"
После нескольких часов работы в поисковых системах и попытке решить ни один из предлагаемых решений не удалось. Здесь я перечислил несколько решений. Я также отметил тот, который работал у меня. (Я использовал EF версии 6.1.1 и SQL Server 2014, но более старый DB)
connectionString="metadata=res://*/DAL.nameModel.csdl|res://*/DAL.nameModel.ssdl|res://*/DAL.nameModel.msl;
(это файлы. Чтобы увидеть их, вы можете переключать Показать все файлы в проводнике решений в каталоге ~/obj/..)... и многие другие, которые я пробовал [например: возврат версии EntityFramework к более поздней версии (не уверен в этом)]
что сработало для меня:
из этой статьи здесь, это помогло мне решить мою проблему. Я только что изменил ProviderManifestToken="2012"
на ProviderManifestToken="2008"
в файле EDMX. Для этого:
Обозреватель решений
Надеюсь, это поможет.
Моя проблема и решение, симптомы были одинаковыми "Не удалось загрузить указанный ресурс метаданных", но основная причина была другой. У меня было 2 проекта, в одном из которых был EntityModel, а другой - для решения. Я фактически удалил и воссоздал файл EDMX в EntityModel.
Решение состояло в том, что мне пришлось вернуться к проекту веб-приложения и добавить эту строку в файл конфигурации. Новая модель изменила несколько элементов, которые необходимо было дублировать в "другом" проекте Web.Config. Старая конфигурация перестала быть хорошей.
<add name="MyEntities"
connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;
provider=System.Data.SqlClient;
provider connection string="
data source=Q\DEV15;initial catalog=whatever;
user id=myuserid;password=mypassword;
multipleactiveresultsets=True;
application name=EntityFramework""
providerName="System.Data.EntityClient" />
Окончательное решение (даже после воссоздания базы данных на двух других машинах, а также EDMX и других sundries) было не использовать первый выпуск Entity Framework. С нетерпением ждем его снова в .NET 4.0.
После того, как я снова столкнулся с одной и той же проблемой и искал ответ, я наконец нашел кого-то, у кого была такая же проблема. Похоже, что строка подключения была неправильно сформирована мастером Visual Studio, а ссылка на ресурсы метаданных отсутствовала в важном пути.
v1.0 BUG?: Не удается загрузить указанный ресурс метаданных. Скрипты!= Модели
Обновление 2013-01-16. Перейдя к почти исключительно с использованием методов EF Code First (даже с существующими базами данных), эта проблема больше не является проблемой. Для меня это было жизнеспособным решением для уменьшения беспорядка из автоматически генерируемого кода и конфигурации и увеличения моего собственного контроля над продуктом.
Это происходит со мной, когда я не очищаю решение перед сборкой нового дизайнера .edmx. Так что просто не забудьте очистить решение, прежде чем создавать новый дизайнер .edmx. Это помогает мне пропустить гораздо больше проблем с этим. Ниже представлены подробности навигации, если вы новичок в Visual Studio.
Click-> Build-> Clean Solution
Затем Click-> Build-> Rebuild Solution
Надеюсь это поможет. Спасибо всем
Для всех вас SelftrackingEntities
Пользователи,
если вы следовали за прохождением Microsoft и разделили класс контекста объекта на
проект службы wcf (путем привязки к контексту .tt), чтобы этот ответ был для вас:
часть показанных ответов в этом сообщении, которая включает в себя код типа:
... = string.Format("res://{0}/YourEdmxFileName.csdl|res://{0}/YourEdmxFileName.ssdl|res://{0}/YourEdmxFileName.msl",
typeof(YourObjectContextType).Assembly.FullName);
НЕ РАБОТАЕТ ДЛЯ ВАС!! причина в том, что YourObjectContextType.Assembly
теперь находится в другой Ассамблее (внутри сборки проекта wcf),
Итак, вы должны заменить YourObjectContextType.Assembly.FullName
на →
ClassTypeThatResidesInEdmProject.Assembly.FullName
получайте удовольствие.
Я написал этот вспомогательный класс для создания экземпляров объектов ObjectContext, когда они определены в другом проекте, чем проект, использующий его. Я разбираю строку подключения в файле конфигурации и заменяю '*' на полное имя сборки.
Это не идеально, потому что он использует отражение для построения объекта, но это самый общий способ сделать это, что я мог найти.
Надеюсь, что это поможет кому-то.
public static class EntityHelper<T> where T : ObjectContext
{
public static T CreateInstance()
{
// get the connection string from config file
string connectionString = ConfigurationManager.ConnectionStrings[typeof(T).Name].ConnectionString;
// parse the connection string
var csBuilder = new EntityConnectionStringBuilder(connectionString);
// replace * by the full name of the containing assembly
csBuilder.Metadata = csBuilder.Metadata.Replace(
"res://*/",
string.Format("res://{0}/", typeof(T).Assembly.FullName));
// return the object
return Activator.CreateInstance(typeof(T), csBuilder.ToString()) as T;
}
}
В моем случае эта проблема была связана с переименованием моего файла модели edmx... исправление строки подключения app.config для файлов csdl/ssdl/msl исправило мою проблему.
Если вы используете конструктор EF 4.0 для генерации вашего csdl/ssdl/msl, эти 3 "файлы" будут фактически сохранены в основном файле edmx модели. В этом случае сообщение Вакаса в значительной степени находится на отметке. Важно понимать, что "Model_Name" в его примере нужно будет изменить на любое текущее имя вашего файла .edmx модели (без .edmx).
Кроме того, если ваш файл edmx не находится на корневом уровне вашего проекта, вам необходимо указать Model_Name с относительным путем, например.
res://*/MyModel.WidgetModel.csdl|res://*/MyModel.WidgetModel.ssdl|res://*/MyModel.WidgetModel.msl
указывает, что csdl/ssdl/msl xml хранится в файле модели 'WidgetModel.edmx', который хранится в папке с именем 'MyModel'.
Исключение связано с тем, что компилятор указывает на не существующие метаданные, поэтому просто скопируйте app.config
connectionstring в Web.config
ConnectionString
С той же проблемой я повторно создал edmx из базы данных. Решает мою проблему.
Была такая же проблема, потому что я переименовал сборку.
Мне также пришлось переименовать его в атрибутах AssemblyTitle и AssemblyProduct в Project Properties/AssemblyInfo.cs, а также удалить и повторно добавить ссылку на файл edmx.
Тогда он работал нормально.
У меня возникли проблемы с этим же сообщением об ошибке. Моя проблема была решена путем закрытия и повторного открытия Visual Studio 2010.
Если вы используете edmx из другого проекта, то в строке подключения измените...
metadata=res://*/Data.DataModel.csdl
... до...
metadata=res://*/DataModel.csdl
Я просто не ссылался на свою библиотеку классов, содержащую файл EDMX.
Плохой файл app.config или web.config может сделать это. Я скопировал строку подключения app.config к моему web.config в своем интерфейсе и в итоге ввел:
<connectionStrings>
<connectionStrings>
<add name="name" connectionString="normalDetails"/>
</connectionStrings>
</connectionStrings>
У меня была та же проблема с решением, которое содержало проекты в папке решения, когда они были перемещены в корневое решение (чтобы преодолеть подозрительную ошибку с Mvc3AppConverter из-за расположения проекта).
Хотя решение, скомпилированное после того, как все * ссылки на проекты были повторно добавлены по мере необходимости, при запуске веб-сайта возникла ошибка.
EDMX находится в одном из проектов, которые были перемещены (проект "Данные" ), но, конечно, отсутствие ссылки на проект Data не вызвало ошибки компиляции, а просто ошибки времени выполнения.
Просто добавив недостающую ссылку на основной проект, разрешив эту проблему, нет необходимости редактировать соединение вообще.
Я надеюсь, что это поможет кому-то другому.
У меня также была та же проблема и решение, что и у Rick, за исключением того, что я импортировал существующий .edmx в новый проект, а в то время как базовое пространство имен не имело значения, оно было импортировано в другой подкаталог, поэтому мне также пришлось обновите строку подключения внутри Web.Config в трех местах, чтобы включить различное имя подкаталога:
Я тоже сталкиваюсь с этой проблемой, я просто чищу и перестраиваю решение, которое отлично работает.
Иногда я вижу эту ошибку в моем проекте. Я решаю это
1 - Щелкните правой кнопкой мыши на файле EDMX
2 - Выберите опцию Run Custom Tool
В моем случае ни один из перечисленных ответов не сработал, и поэтому я публикую это.
В моем случае работа на Visual Studio и запуск с IIS Express работали нормально. Но когда я развертывал с использованием сценариев Nant в качестве автономного веб-сайта, возникали ошибки. Я перепробовал все приведенные выше предложения, а затем понял, что DLL, сгенерированная скриптом nant, была намного меньше, чем сгенерированная VS. И тогда я понял, что Нант не смог найти файлы .csdl,.msl и .ssdl. Таким образом, существует два способа решения этой проблемы: один - скопировать необходимые файлы после того, как Visual Studio их сгенерирует, и включить их в развертывание сборки. А затем в Web.config укажите путь как:
"metadata=~/bin/MyDbContext.csdl|~/bin/MyDbContext.ssdl|~/bin/MyDbContext.msl;provider=System.Data.SqlClient;...."
Это предполагает, что вы вручную скопировали файлы в каталог bin сайта, на котором вы работаете. Если он находится в другом каталоге, измените путь соответствующим образом. Второй способ - выполнить EdmGen.exe в сценарии Nant и сгенерировать файлы, а затем включить их в качестве ресурсов, как показано в примере ниже: https://github.com/qwer/budget/blob/master/nant.build
У меня возникла проблема после перемещения большого решения из одной папки в Source Control Explorer в другую. Мы не проверяем папку пакета в Team Foundation, и поэтому я думаю, что VS скачал пакеты автоматически. Это улучшило мою форму EF v6.1.2 до v6.1.3.
Проблема исчезла, когда я отказался от оригинала v6.1.2.
В моем случае это было связано с тем, что я строю строку соединения с помощью EntityConnectionStringBuilder. Убедитесь, что свойство Metadata использует имя модели (включая пространство имен)
Просто введите путь следующим образом вместо {Path.To.The.}: res:///{Path.To.The.} YourEdmxFileName.csdl | res:///{Path.To.The.} YourEdmxFileName.ssdl | Рез://*/{.} Path.To.The YourEdmxFileName.msl
Я получил эту ошибку, когда мой файл emdx был удален командой prebuild, довольно просто. Некоторое время назад я понял, что это так просто.
Используя информацию этот блогпост:
Как и другие, res:\\является указателем на ваши ресурсы. Чтобы проверить и убедиться, что имена ваших ресурсов верны, вы можете использовать декомпилятор, например DotPeek от JetBrains, чтобы открыть файл .dll и просмотреть ваши файлы ресурсов.
Или вы можете открыть окно просмотра во время отладки и вставки этого кода, чтобы получить массив имен ресурсов в текущей исполняемой сборке.
System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames()
При этом формат ваших путей метаданных должен выглядеть примерно так:
{my-assembly-name}/{возможно-a-namespace}. {class-name}. {csdl или ssdl или msl}
У меня была эта проблема вчера и я смотрел на свой код в отладке и на выходе из SQL Profiler.
То, что я не мог понять, прежде чем я прочитал и понял это сообщение, объяснял, почему EntityFramework выбрасывает эту ошибку, поскольку она вызывала БД. Я просматривал сотни строк в SQL Profiler, пытаясь выяснить, что не так с моделью базы данных. Я не мог найти ничего подобного тому, что ожидал, и, честно говоря, я не был уверен, что искал.
Если вы находитесь в этом положении, проверьте строку подключения. Я предполагаю, что до того, как EntityFramework создаст свой SQL, он проверит модель, указанную в части метаданных строки подключения. В моем случае это было неправильно. EntityFramework даже не делал это до БД.
Убедитесь, что имена верны. Как только я выяснил это, я увидел вызовы в SQL Profiler, где ApplicationName был "EntityFramework" с SQL, вызывающим ожидаемые таблицы.
Аналогичная проблема для меня. Имя моего класса отличается от моего имени файла. Сгенерированная строка соединения имела имя класса, а не имя файла. Решение для меня было просто переименовать мой файл в соответствии с именем класса.
Когда я выяснил проблему метаданных, у меня возникла следующая проблема в виде исключения invokation, неспособного найти строку соединения для XXXEntities в app.config(где моя цель не зависела от app.config), Благодаря чистой удаче я обнаружил, что ссылка на System.Data в моем проекте unit test очистила это последнее препятствие. Итак, подведем итог:
Теперь у меня есть свои метаданные в библиотеке классов, которые могут обновляться из ссылки db, и я могу указать свои приложения и модульные тесты на любой db на любом сервере во время выполнения.
Добавление: Когда я переместил edmx в папку, я снова получил ошибку. После небольшого исследования я обнаружил, что вы хотите, чтобы ваша строка метаданных выглядела так: metadata = res://EPM.DAL/Models.EPM.csdl, где EPM.DAL - это имя сборки, а EPM.edmx - папка моделей.
Что касается меня, я разделил уровень доступа к данным и уровень пользовательского интерфейса. Поэтому у меня есть строка подключения сущности для каждого слоя.
Прежде чем изменять эти две разделенные строки подключения, я все равно обнаружил, что ниже ошибки.
Unable to load the specified metadata resource
Таким образом, я делаю для тех же строк соединения для этих двух слоев (DAL, UI), он работает идеально.
Мое решение состоит в том, чтобы сделать все строки подключения одинаковыми независимо от того, где они уже были представлены.
Иногда сборка, содержащая модель, не загружается:
[TestMethod]
public void TestOpenWithConfigurationAfterExplicit()
{
String dummy = typeof(MallApp).Assembly.FullName;
//force the assembly loaded.
using (DbContext ctx = new DbContext("name=MyContainer))
{
}
}
Тип MallApp
живет в той же сборке, что и модель сущности. Без явной загрузки будет выброшено System.Data.MetadataException
.
Другой причиной этого исключения является включение связанной таблицы в ObjectQuery, но введите неправильное имя свойства навигации.
Пример:
var query = (from x in myDbObjectContext.Table1.Include("FKTableSpelledWrong") select x);
Моя теория заключается в том, что если у вас более одного файла edmx с таким же именем (например, Model1), это даст это исключение. У меня такая же проблема, когда я решил назвать все мои файлы edmx (сидя в разных проектах) как Model1, потому что я думал, что они должны быть независимыми.