Не удается подключиться к LocalDB
Я пытаюсь запустить приложение, размещенное на IIS (в форме базы данных фильмов), чтобы научиться проектировать программу трехуровневой архитектуры: приложение MVC, службы WCF, база данных SQL Server. Поскольку у меня нет лицензионного ключа для полного SQL Server, я решил пойти с LocalDB и иметь службы WCF, которые обертывают мои хранимые процедуры. Это первый раз, когда я использую LocalDB и сталкиваюсь с проблемами, связанными с моим экземпляром, v13.0.
Моя проблема:
На всю жизнь я не могу заставить свой проект в VS подключиться к экземпляру LocalDB. Я продолжаю получать следующую ошибку:
При установке соединения с SQL Server произошла ошибка, связанная с сетью или экземпляром. Сервер не найден или не был доступен. Убедитесь, что имя экземпляра указано правильно и что SQL Server настроен для разрешения удаленных подключений. (поставщик: сетевые интерфейсы SQL, ошибка: 50 - произошла ошибка времени выполнения локальной базы данных. Указанный экземпляр LocalDB не существует.
Моя строка подключения (из Web.config):
<connectionStrings>
<add name="MovieDB" connectionString="Data Source=(localdb)\v13.0;Initial Catalog=MovieDB;Integrated Security=True;AttachDbFilename=|DataDirectory|\MovieDB.mdf" />
</connectionStrings>
Использование sqlcmd для подключения к нему и выполнения запросов работает нормально:
Visual Studio SQL Server Object Explorer может просто подключиться:
Строка подключения, экранированная Visual Studio, когда она попадает в проблемную строку, поэтому я знаю, что строка подключения не экранирована неправильно:
"Data Source=(localdb)\\v13.0;Initial Catalog=MovieDB;Integrated Security=True;AttachDbFilename=|DataDirectory|\\MovieDB.mdf"
Я попытался следовать этому руководству ( часть 1 и часть 2), и изображения были повреждены, по крайней мере, 18.04.2016, поэтому я не смог полностью понять, что я должен делать. Я смог получить только вышеуказанную ошибку, потому что я изменил удостоверение пула приложений на LocalSystem:
Когда пул приложений выполняется под идентификатором ApplicationPoolIdentity, я получаю эту ошибку:
При установке соединения с SQL Server произошла ошибка, связанная с сетью или экземпляром. Сервер не найден или не был доступен. Убедитесь, что имя экземпляра указано правильно и что SQL Server настроен для разрешения удаленных подключений. (поставщик: сетевые интерфейсы SQL, ошибка: 50 - Произошла ошибка локальной базы данных во время выполнения. Не удалось получить путь к данным локального приложения. Скорее всего, профиль пользователя не загружен. Если LocalDB выполняется в IIS, убедитесь, что загрузка профиля включена для текущий пользователь.
Я даже зашел так далеко, что изменил файл C:\windows\system32\inetsrv\config\applicationHost.config для принудительной загрузки профиля. Еще ничего.
<applicationPools>
<add name="DefaultAppPool" />
<add name="Classic .NET AppPool" managedRuntimeVersion="v2.0" managedPipelineMode="Classic" />
<add name=".NET v2.0 Classic" managedRuntimeVersion="v2.0" managedPipelineMode="Classic" />
<add name=".NET v2.0" managedRuntimeVersion="v2.0" />
<add name=".NET v4.5 Classic" managedRuntimeVersion="v4.0" managedPipelineMode="Classic" />
<add name=".NET v4.5" managedRuntimeVersion="v4.0">
<!-- I added this, before it was an empty node -->
<processModel identityType="ApplicationPoolIdentity" loadUserProfile="true" setProfileEnvironment="true" />
</add>
<applicationPoolDefaults managedRuntimeVersion="v4.0">
<!-- This was already here -->
<processModel identityType="ApplicationPoolIdentity" loadUserProfile="true" setProfileEnvironment="false" />
</applicationPoolDefaults>
</applicationPools>
Мое приложение работает в пуле приложений.NET 4.5
Мой код:
Страница загружает и вызывает этот сервис, чтобы получить список фильмов в БД:
[ServiceContract]
public interface IMovieDBService
{
// ...
[OperationContract]
List<Movie> GetMovies(int actorID);
// ...
}
public class MovieDBService : IMovieDBService
{
// ...
public List<Movie> GetMovies(int actorID = 0)
{
var output = new List<Movie>();
using (var connection = DBTools.GetConnection(MovieDBConnectionName)) // Does not get past here; MovieDBConnection = "MovieDB"
{
var parameters = new List<SqlParameter>
{
new SqlParameter("@actorID", actorID)
};
using (var reader = connection.ExecuteStoredProcedure("GetMovies", parameters))
{
while (reader.Read())
{
output.Add(new Movie
{
ID = reader.GetInt32("ID"),
Title = reader.GetString("Title"),
Year = reader.GetInt16("Year"),
Genre = GetGenre(reader.GetInt32("GenreID"))
});
}
}
}
return output;
}
// ...
}
И проблемный метод из моего проекта DBTools:
public static SqlConnection GetConnection(string connectionName)
{
var connection = new SqlConnection();
var connectionString = ConfigurationManager.ConnectionStrings[connectionName];
if (connectionString != null)
{
connection.ConnectionString = connectionString.ConnectionString;
connection.Open(); // breaks here
return connection;
}
return null;
}
Я могу только предположить, что проблема связана с аутентификацией или с тем фактом, что приложение, размещенное на IIS, пытается подключиться к пользовательскому процессу LocalDB, но я пытался следовать инструкциям из других вопросов и не смог (возможно, из-за сбоя). чтобы понять реальную проблему). Я в растерянности...
3 ответа
Попробуйте это: в вашем файле applicationhost попробуйте изменить processModel identityType на SpecificUser, а также включить имя пользователя и пароль. ИЛИ измените удостоверение пула приложений на пользователя, у которого есть разрешение на базу данных. Когда вы работаете как удостоверение пула приложений, на основе ваших снимков экрана вы работаете как локальная система - которая является предопределенной локальной учетной записью, тогда как sqlcmd работает как пользователь, вошедший в систему как пользователь.
Проблема в том, что ваша учетная запись пула приложений IIS не может видеть экземпляр localdb, потому что только учетная запись, создавшая экземпляр, может получить к нему доступ, что, скорее всего, является вашей личной учетной записью пользователя. Вы можете поделиться им с другими пользователями на вашем компьютере (например, учетными записями пула приложений IIS), выполнив эту команду:
sqllocaldb share v13.0 v13.0_shared
Мы разделяем
v13.0
экземпляр и имя общего экземпляра
v13.0_shared
. Тогда вы бы изменили
Data Source
часть вашей строки подключения к этому:
Data Source=(localdb)\.\v13.0_shared
Обратите внимание на ведущую
.\
перед именем экземпляра. Это указывает на то, что вы хотите подключиться к общему экземпляру.
Теперь все ваши пулы приложений IIS смогут подключаться к экземпляру localdb без необходимости настраивать разрешения для каждого из них.