Я пытаюсь создать новую базу данных, используя первую концепцию кода Entity Framework. Однако при запуске кода база данных не создается (используя параметр DropCreateDatabaseIfModelChanges
), хотя код работает нормально. Я вижу следующее исключение, когда пытаюсь получить что-то из базы данных.
Мой проект настраивается с использованием отдельного слоя DataAccess
с общей конструкцией сервиса и хранилища. Таким образом, все мои сущности, репозиторий и контекст базы данных находятся в отдельном проекте в рамках решения.
Мой global.asax
файл содержит следующий фрагмент кода.
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<MyContext>());
Это должно инициализировать новую базу данных, если ее нет, правильно?
Мой класс контекста базы данных выглядит следующим образом:
namespace Website.DAL.Model
{
public class MyContext : DbContext
{
public IDbSet<Project> Projects { get; set; }
public IDbSet<Portfolio> Portfolios { get; set; }
/// <summary>
/// The constructor, we provide the connectionstring to be used to it base class.
/// </summary>
public MyContext()
: base("MyConnectionString")
{
}
static MyContext()
{
try
{
Database.SetInitializer<MyContext>(new DropCreateDatabaseIfModelChanges<MyContext>());
}
catch (Exception)
{
throw;
}
}
/// <summary>
/// This method prevents the plurarization of table names
/// </summary>
/// <param name="modelBuilder"></param>
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<System.Data.Entity.ModelConfiguration.Conventions.PluralizingTableNameConvention>();
}
}
}
Я создал этот класс, следуя нескольким учебникам и статьям в Интернете. Все это ново для меня, но насколько я вижу, все кажется правильным до сих пор. Итак, теперь два объекта, которые я использую. Их называют "Проект" и "Портфолио". Они выглядят так:
public class Portfolio
{
[Key]
public Guid Id { get; set; }
public String Name { get; set; }
public DateTime StartDate { get; set; }
public DateTime? EndDate { get; set; }
public bool IsPublished { get; set; }
public virtual ICollection<Project> Projects { get; set; }
}
и
public class Project
{
[Key]
public Guid Id { get; set; }
public DateTime StartDate { get; set; }
public DateTime? EndDate { get; set; }
public bool IsPublished { get; set; }
public String Title { get; set; }
}
База данных, которую я использую, работает на внешнем сервере, она поставляется с хостинг-провайдером, который я использую. У меня есть база данных SQL Server, и строка подключения к базе данных находится в web.config
проекта веб-сайта. Я уже попытался удалить базу данных и позволить ее воссоздать, что, к сожалению, не сработало. Я пропустил что-то очевидное здесь? Или это может быть просто, как права доступа к серверу для создания баз данных?
Примечание. Когда я запускаю команду Database-Update -Script
для генерации кода SQL, кажется, что создаются правильные операторы SQL для создания всех таблиц.
ОБНОВЛЕНИЕ 1: Хорошо, благодаря некоторым комментариям я пришел немного дальше. Я добавил два свойства для своих объектов, чтобы внести некоторые изменения, и также создал пользовательский инициализатор, например:
public class ForceDeleteInitializer : IDatabaseInitializer<MyContext>
{
private readonly IDatabaseInitializer<MyContext> _initializer = new DropCreateDatabaseIfModelChanges<MyContext>();
public ForceDeleteInitializer()
{
//_initializer = new ForceDeleteInitializer();
}
public void InitializeDatabase(MyContext context)
{
//This command is added to prevent open connections. See http://stackoverflow.com/info/5288996/database-in-use-error-with-entity-framework-4-code-first
context.Database.ExecuteSqlCommand("ALTER DATABASE borloOntwikkel SET SINGLE_USER WITH ROLLBACK IMMEDIATE");
_initializer.InitializeDatabase(context);
}
}
Я также удалил инициализатор из конструктора моего контекста, так что это означает, что я удаляю эту строку кода;
Database.SetInitializer<MyContext>(new DropCreateDatabaseIfModelChanges<MyContext>());
После этого я добавил эти три строки в мой файл Global.asax;
Database.SetInitializer(new ForceDeleteInitializer());
MyContext c = new MyContext();
c.Database.Initialize(true);
При отладке я получаю это исключение;
Это дает мне следующую информацию:
- InnerException говорит: поставщик не возвратил ProviderManifestToken
- InnerException в InnerException говорит: "Для этой операции требуется подключение к базе masterdatabase. Соединение не может быть сделал ширину "основной" базы данных, поскольку исходное соединение и ссылки были удалены из соединения. Предоставьте не открытое соединение "
После этих действий база данных недоступна, поэтому, скорее всего, она удалена.
Что можно сделать по этому поводу? Скорее всего, я не могу получить доступ к основной базе данных, потому что мой хостинг-провайдер не даст мне надлежащего права на доступ.