Ошибка использования базы данных с первым кодом Entity Framework 4
у меня есть приложение MVC3 и EF 4 Code First, которое настроено на изменение DB при изменении модели, установив инициализатор DB в DropCreateDatabaseIfModelChanges<TocratesDb>, где TocratesDb мой производным DbContext.
теперь я внес изменения в модель, добавив свойства в класс, но когда EF пытается удалить и воссоздать БД, я получаю следующую ошибку:
Cannot drop database "Tocrates" because it is currently in use.
у меня нет абсолютно никаких других соединений, открытых в этой базе данных. Я предполагаю, что мой cDbContext все еще есть открытое соединение с базой данных, но что я могу с этим поделать?
NEW: теперь моя проблема заключается в том, как повторно создать базу данных на основе модели. Используя более общий IDatabaseInitializer, я теряю это и должен реализовать его сам.
6 ответов:
ваш текущий контекст должен иметь открытое соединение, чтобы иметь возможность удалить базу данных. Проблема в том, что могут быть другие открытые соединения, которые будут блокировать ваш инициализатор БД. Одним из очень хороших примеров является открытие любой таблицы из вашей базы данных в Management studio. Другой возможной проблемой могут быть открытые соединения в пуле соединений вашего приложения.
в MS SQL этого можно избежать, например, переключив БД в однопользовательский режим и принудительно подключив все соединения для закрытия и отката незавершенных транзакций:
ALTER DATABASE Tocrates SET SINGLE_USER WITH ROLLBACK IMMEDIATEвы можете создать новый intializer, который сначала вызовет эту команду, а затем отбросит базу данных. Имейте в виду, что вы должны обрабатывать подключение к базе данных самостоятельно, потому что
ALTER DATABASEиDROP DATABASEдолжен быть вызван по тому же соединению.Edit:
здесь у вас есть пример использования шаблона декоратора. Вы можете изменить его и инициализировать внутренний инициализатор внутри конструктора вместо его передачи в качестве параметра.
public class ForceDeleteInitializer : IDatabaseInitializer<Context> { private readonly IDatabaseInitializer<Context> _initializer; public ForceDeleteInitializer(IDatabaseInitializer<Context> innerInitializer) { _initializer = innerInitializer; } public void InitializeDatabase(Context context) { context.Database.SqlCommand("ALTER DATABASE Tocrates SET SINGLE_USER WITH ROLLBACK IMMEDIATE"); _initializer.InitializeDatabase(context); } }
Я нашел в EF 6 это не удается с
ALTER DATABASE statement not allowed within multi-statement transactionошибка.решение состояло в том, чтобы использовать новую перегрузку поведения транзакции следующим образом:
context.Database.ExecuteSqlCommand(TransactionalBehavior.DoNotEnsureTransaction, "ALTER DATABASE [" + context.Database.Connection.Database + "] SET SINGLE_USER WITH ROLLBACK IMMEDIATE");
У меня была та же проблема.
Я разрешил его, закрыв соединение, открытое в представлении обозревателя серверов Visual Studio.
Я понимаю, что это датировано, но я не мог заставить принятое решение работать, поэтому я свернул быстрое решение...
using System; using System.Data.Entity; namespace YourCompany.EntityFramework { public class DropDatabaseInitializer<T> : IDatabaseInitializer<T> where T : DbContext, new() { public DropDatabaseInitializer(Action<T> seed = null) { Seed = seed ?? delegate {}; } public Action<T> Seed { get; set; } public void InitializeDatabase(T context) { if (context.Database.Exists()) { context.Database.ExecuteSqlCommand("ALTER DATABASE [" + context.Database.Connection.Database + "] SET SINGLE_USER WITH ROLLBACK IMMEDIATE"); context.Database.ExecuteSqlCommand("USE master DROP DATABASE [" + context.Database.Connection.Database + "]"); } context.Database.Create(); Seed(context); } } }это работает для меня и поддерживает легко высева.
в Visual Studio 2012,Обозреватель объектов SQL Server окно может содержать подключение к базе данных. Закрытие окна и все открытые из него окна освобождает соединение.
простое закрытие всего моего проекта и его повторное открытие сделали трюк для меня. Это самый простой способ убедиться, что все еще нет открытых соединений
Comments