Указанное именованное соединение либо не найдено в конфигурации, либо не предназначено для использования с поставщиком EntityClient, либо недействительно

170

У меня есть один объектный объектный фреймворк, и когда я добавляю его в свой проект, connectionstring он добавляется app.configв connectionstringраздел, но когда я хочу создать новый entitycontextи использовать его connectionstring, появляется эта ошибка

user421413
источник
4
Спасибо за ссылку, Крейг. Я голосую, чтобы сохранить эту ветку, потому что заголовок был тем, что помогло мне найти ошибку MetadataException.
jp2code
Это случилось со мной, когда файл конфигурации не обновлялся со строкой подключения по какой-то странной причине.
P.Brian.Mackey

Ответы:

217

Я подозреваю, что ваша проблема проистекает из того факта, что у вас есть более одного проекта в вашем решении, и тот, который содержит материал вашей структуры сущностей, включая edmxфайлы, НЕ является стартовым проектом решений. В этом случае, даже если строка подключения существует в проекте EF app.config, CLR все равно не может найти ее во время выполнения. Например, если у вас есть веб-сайт и проект EF в вашем решении, вам необходимо скопировать строку подключения из проекта EF app.configна ваш веб-сайт web.config. По сути, любые данные строки подключения должны существовать в файле конфигурации проекта, из которого инициируются потоки .Net с помощью CLR (т. Е. Вашего запускаемого проекта). Если это не ваш случай, просто откройтеedmxфайл, щелкните правой кнопкой мыши на его поверхности, выберите свойства, скопируйте строку подключения и вставьте ее в app.configраздел «Строка подключения». Таким образом, вы можете убедиться, что у вас есть правильный в вашей конфигурации.

РЕДАКТИРОВАТЬ:
Как вы можете видеть здесь в документации по конструктору ObjectContext , первый параметр - это имя строки соединения, которая является кодом, сгенерированным во время создания вашего EDM. Если каким-то образом имя вашей строки подключения случайно изменится, все, что вам нужно сделать, это щелкнуть правой кнопкой мыши по вашей модели и выбрать «Обновить модель из базы данных ...», а затем следуйте указаниям мастера, чтобы обновить конфигурацию и конструктор, чтобы отразить это. изменение.

Мортеза Манави
источник
1
привет, Мортеза, и спасибо за ваш ответ, но я ранее скопировал секту строки подключения в web.config, но ошибка не устранена, но когда в entitymodel.designer заменяют (public EntityContext (): base ("name = EntityContext", EntityContext " )) с этой
строкой
1
@Morteza, у вас есть решение для проектов, в которых у исполняющей сборки нет app.config? В моем случае вызывающий исполняемый файл - это приложение VB6, которое вызывает мою сборку (где находятся объекты сущностей) через COM Interop.
Скоропортящийся Дейв
4
так просто, но так расстраивает. ГОЛОСОВАНИЕ Да здравствует переполнение стека!
granadaCoder
3
Если вы используете WCF, не забудьте включить строку подключения в ваш сервисный проект
Nathan
1
Спасибо Мортеза, сэкономил мне много времени!
Крис
32

Вам необходимо скопировать строку подключения в app.config в ваш web.config или скопировать весь файл в проект, который отображает вывод. Это одно из условий потребления фреймворка.

Musikero31
источник
1
просто добавьте ту же строку подключения (как в проекте доступа к данным) в ваш файл web.config (находится в проекте переднего плана).
датский
@ Musikero31 Я использую EF и определяю все строки соединения сущностей в коде. У меня нет ничего в конфигурации, связанной с этим.
Кит Борода
После того, как я скопировал файлы DAL в новый проект, я также получил вышеуказанную ошибку. Присмотревшись ближе к файлам конфигурации, я заметил, что строка подключения была заменена на EF. Мне удалось вручную скопировать / вставить правильную строку подключения в новый проект, и это сработало.
Рави Рам
9

Я столкнулся с этой проблемой, когда попытался поместить свою собственную логику базы данных в .dll для использования несколькими проектами в моем решении.

В то время как у .dll был правильный файл app.config, он не работал. Платформа сущностей хотела получить информацию о соединении в файле app.config .exe. Копирование информации туда работало просто отлично.

Решение Мортезы о вставке строки подключения непосредственно в .edmx не сработало для меня, так как не позволило мне вставить туда значение - хотя именно это я и хотел сделать.

Уолт Стоунбернер
источник
3
Несмотря на то, что в каталоге моего exe-файла был только app.config (и это был единственный файл конфигурации в этом каталоге), он не мог его прочитать. Мне пришлось переименовать файл myExe.exe.config
Mario
6

Привет, у меня была эта проблема, и это сводило меня с ума. Во всяком случае, наконец, я понял, в чем проблема. Первое, что вам нужно сделать, это убедиться, что connectionstringsв app.configи web.configодинаковы. Затем вы должны дважды щелкнуть .edmxфайл, чтобы увидеть таблицы. Как только вы нажмете где-нибудь рядом с таблицами, но не на таблицы и перейдите к свойствам. В раскрывающемся списке выберите ConceptualEntityModelи найдите имя контейнера сущностей и хорошо его запомните.

Затем перейдите к конструктору файла edmx и откройте конструкторы. (конструктор - это подпапка файла edmx) конструкторы должны иметь два параметра в параметре BASE

public DBEntities() : base("name=DBEntities", "DBEntities")
    {
        this.ContextOptions.LazyLoadingEnabled = true;
        OnContextCreated();
    }

Это одна из них. первый параметр должен иметь имя файла проекта, в котором он .edmxнаходится. Второй параметр должен иметь имя имени контейнера сущности из свойств, о которых я упоминал ранее. не забудьте расположить все конструкторы с помощью:base("", "")

По крайней мере, это была моя проблема, и моя проблема была решена таким образом. Я надеюсь, что вам удастся решить вашу, как это.

MaltaCoders
источник
6

У меня была вариация на эту тему, которую никто, казалось, не освещал.

У меня был основной проект с парой моделей и тестовый проект, содержащий юнит-тесты. Тестовый проект работал, но затем остановился с ошибкой, упомянутой в ОП. Я не делал переименования или перемещения файла EDMX.

В большинстве советов упоминалось сравнение файлов .config, но в моем проекте их вообще не было.

В конце я скопировал файл app.config из основного проекта в свой тестовый проект, и тогда он заработал. Является ли это правильным шагом или будет представлять проблемы с ремонтопригодностью при добавлении дополнительных моделей, я не знаю, но по крайней мере мои модульные тесты теперь снова работают правильно.

С. Багги
источник
Разместив это, я понял, что, вероятно, будет лучше создать ссылку на файл app.config другого проекта. Но все же, другой подход будет работать для исправления исходной проблемы, когда файл конфигурации вообще отсутствует.
С. Бэгги,
4

Хотя ответ Мортезы Манави действительно решает эту проблему, другое решение заключается в динамическом построении строки подключения и передаче ее в конструктор для вашего ObjectContext:

public static string CreateConnectionString()
{
    var assemblyPath = Assembly.GetExecutingAssembly().Location;
    string assemblyLocation = Path.GetDirectoryName(assemblyPath);
    string dbPath = Path.Combine(assemblyLocation, "YourDatabase.sdf");
    var sqlBuilder = new SqlConnectionStringBuilder { DataSource = dbPath };

    var entityBuilder = new EntityConnectionStringBuilder
    {
        ProviderConnectionString = sqlBuilder.ConnectionString,
        Provider = "System.Data.SqlServerCe.3.5",
        Metadata = @"res://*/YourModel.csdl|
                 res://*/YourModel.ssdl|
                 res://*/YourModel.msl"
    };

    return entityBuilder.ToString();
}

// Snip...

var entityContext = new YourObjectContext(CreateConnectionString());

Это избавляет от необходимости копировать информацию строки подключения в app.config вашего запускаемого проекта, что, по крайней мере, в моем случае, было нежелательно.

Ник Шпрайцер
источник
4

Я забыл добавить providerName = "System.Data.EntityClient" в качестве атрибута в строке подключения. Это привело к этой ошибке, так

<add name="connectionName" connectionString="metadata=res://*/..." providerName="System.Data.EntityClient" />

вместо того

<add name="connectionName" connectionString="metadata=res://*/..." />
Gertjan
источник
2

Я только что обнаружил, что если приложение будет создано в IIS из VS2010 на двух уровнях от корня веб-сайта, эта ошибка произойдет. Не уверен, почему это происходит, нужно будет расследовать больше. Например, если ваше приложение находится по этому пути: /admin/advertiserошибка появится, если /adminна вашем сайте IIS нет виртуального каталога.

Все, что я сделал, это создал пустой adminкаталог, в котором моя .../intepub/wwwrootошибка исчезла.

Вы обнаружите, что не сможете начать отладку, пока не выполните шаг выше.

У нас была эта проблема в нашей команде в прошлом, потребовалось некоторое время, чтобы вспомнить, но именно это мы и исправили раньше.

Йовица Зарик
источник
1

Я использую более позднюю архитектуру и получил ту же проблему, но эта поможет мне. Надеюсь, это поможет вам. Сначала у вас есть то же самое connection string, librariesгде вы можете получить доступ к БД, как в, app.configи web.config после этого вы просто добавляете перегруженный конструктор в файл .edmx (Model.context.cs), что теперь у вас есть два конструктора, один по умолчанию, а другой, который вы только что добавили ( перегружена).

        public YourEntityName(string connString)
            : base(connString)
        {
        }
Мухаммед Асад
источник
1

У меня была библиотека классов, которая тоже не хотела работать с EF. После того, как я скопировал app.config (или просто раздел строки соединения) из моей библиотеки классов в exe-проект, соединение заработало нормально! Вероятно, файл конфигурации должен находиться в той же папке, что и exe-проект, и поэтому не был найден. Поэтому всегда будьте особенно осторожны, когда файл конфигурации используется в проекте библиотеки классов!

Винсент
источник
0

Ну ... эта проблема может быть также по очень простой (глупой) причине ... Я скопировал файл из другого проекта и забыл изменить ConnectionString на EntityDataSource ... как я был в начале проекта и случилось на странице входа в систему я подумал, что это что-то в конфиге, но это было просто неправильное имя строки подключения (и DefaultContainerName).

Габриэль Г
источник