Как я могу получить свою базу данных для заполнения, используя Entity Framework CodeFirst? - PullRequest
62 голосов
/ 11 июня 2011

База данных успешно создана (как и таблицы), но не заполнена.Я провел несколько часов и прочитал тонны статей, но так и не смог его получить.Любые предложения?

В примечании, можно ли вызвать инициализатор без ссылки на мой DatabaseContext в клиенте?

Я включил весь соответствующий код, который мог придумать.Если что-нибудь еще поможет, пожалуйста, дайте мне знать.

Вещи, которые я пробовал:

  1. Я удалил строку подключения (так как в любом случае по умолчанию используется sqlexpress, только имя изменилось)
  2. Я изменил DropCreateDatabaseIfModelChanges на DropCreateDatabaseAlways, все то же самое.

Редактировать: действительно странная вещь - это сработало один раз, но я понятия не имею, как или почему это снова сломалось.Я предполагаю строки подключения, но кто знает.

DatabaseInitializer.cs

public class DatabaseInitializer : DropCreateDatabaseIfModelChanges<DatabaseContext>
{
  protected override void Seed(DatabaseContext context)
  {
    // Seeding data here
    context.SaveChanges();
  }
}

DatabaseContext.cs

public class DatabaseContext : DbContext
{
  protected override void OnModelCreating(DbModelBuilder mb)
  {
    // Random mapping code
  }

  public DbSet<Entity1> Entities1 { get; set; }
  public DbSet<Entity2> Entities2 { get; set; }

}

Global.asax.cs - Application_Start ()

protected void Application_Start()
{
  Database.SetInitializer<DatabaseContext>(new DatabaseInitializer());
  AreaRegistration.RegisterAllAreas();
  RegisterGlobalFilters(GlobalFilters.Filters);
  RegisterRoutes(RouteTable.Routes);
}

Клиент web.config

<connectionStrings>
  <add name="DatabaseContext" connectionString="data source=.\SQLEXPRESS;Database=Database;Integrated Security=SSPI;" providerName="System.Data.SqlClient" />
</connectionStrings>

РЕШЕНИЕ

Ради документации я поделюсь своим решением здесь.Навигация по всем комментариям была бы болью в любом случае.В конце концов у меня были DatabaseInitializer и DatabaseContext в отдельных классах.Я не совсем понимаю, хотя эти крошечные изменения исправили это, но вот оно.

DatabaseInitializer.cs

public class DatabaseInitializer : CreateDatabaseIfNotExists<DatabaseContext>
{
  protected override void Seed(DatabaseContext context)
  {
    // Seed code here
  }
}

DatabaseContext.cs

public class DatabaseContext : DbContext
{
  public DatabaseContext() : base("MyDatabase") { }

  protected override void OnModelCreating(DbModelBuilder mb)
  {
    // Code here
  }

  public DbSet<Entity> Entities { get; set; }
  // Other DbSets
}

Global.asax.cs - Application_Start ()

protected void Application_Start()
{
  Database.SetInitializer(new DatabaseInitializer());
  AreaRegistration.RegisterAllAreas();
  RegisterGlobalFilters(GlobalFilters.Filters);
  RegisterRoutes(RouteTable.Routes);
}

Ответы [ 12 ]

0 голосов
/ 05 января 2012

Это только что случилось со мной, когда я обнаруживал особенности Code First.Такая ситуация часто возникает, когда вы впервые использовали Code First для создания базы данных без какой-либо стратегии инициализации.

Если вы решите сделать это позже, реализовав стратегию на основе DropCreateDatabaseIfModelChanges, но без изменения модели, тоВаш метод Seed не будет вызван, поскольку создание базы данных и ваша стратегия будут применяться только при следующем изменении вашей модели.

Если это произойдет с вами, просто попробуйте немного изменить свою модель, чтобы протестироватьэта гипотеза, и я держу пари, ваша база данных будет заполнена;)

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

0 голосов
/ 11 июня 2011

Событие seed в вашем примере будет запущено только один раз, так как при использовании DropCreateDatabaseIfModelChanges вы можете изменить это значение на DropCreateDatabaseAlways, я думаю, и оно должно запускать событие seed каждый раз.

Редактировать

Это мой DataContext

public WebContext()
{   
    DbDatabase.SetInitializer(new DropCreateDatabaseIfModelChanges<WebContext>());
}
...