Entity Framework Code-first данные по умолчанию в базе данных

Как поступать в ситуациях, когда мне нужны уже существующие данные до запуска приложения или сразу после создания базы данных. Например, у меня есть список стран, которые я хотел бы загрузить в базу данных после того, как code-first сгенерирует его. Как мне это сделать?

Приложение структурировано следующим образом:

Repository > Service > WebMVC

XML находится в проекте WebMVC.


person Shawn Mclean    schedule 13.04.2011    source источник


Ответы (3)


Вы создаете собственный инициализатор, который наследуется от интерфейса DropCreateDatabaseIfModelChanges или DropCreateDatabaseAlways. Нравиться:

public class EntitiesContextInitializer : DropCreateDatabaseIfModelChanges<-YourDbContext->

И затем вы перезаписываете метод Seed, например:

protected override void Seed(YourDbContext context)

Весь пример может выглядеть так:

public class EntitiesContextInitializer : DropCreateDatabaseIfModelChanges<EntitiesContext>
{
    protected override void Seed(EntitiesContext context)
    {
        List<Role> roles = new List<Role>
        {
            new Role {Id=1, Title="Admin"},
            new Role {Id=2, Title="ProjectManager"},
            new Role {Id=3, Title="Developer"}
        };

        // add data into context and save to db
        foreach (Role r in roles)
        {
            context.Roles.Add(r);
        }
        context.SaveChanges();

    }
}

Редактировать: после настройки вам также необходимо настроить Initializer, как упоминал Ладислав Мрнка.

Database.SetInitializer(new EntitiesContextInitializer());

т.е.: в Global.asax:

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

Не забудьте добавить using System.Data.Entity; .....

person Damb    schedule 13.04.2011
comment
Это создаст только список ролей. Вы должны добавить их в контекст и сохранить изменения. - person Ladislav Mrnka; 14.04.2011
comment
@Dampe Могу ли я использовать Database.SetInitializer в проекте webUI или он должен быть там, где я создаю DbContext? - person Shawn Mclean; 14.04.2011
comment
@Lol coder: Вы можете добавить его в файл Global.asax в метод Application_Start. Вам нужно будет добавить Using.System.Data.Entity; - person Damb; 14.04.2011
comment
По какой-то причине он выполняет метод Database.SetInitializer, но не выполняет метод Seed. Я установил в нем точки останова, и ничего не произошло. - person Shawn Mclean; 14.04.2011
comment
Я не знаю, что может быть не так. Меня устраивает. Возможно, ваша база данных уже заполнена, и вы используете DropCreateDatabaseIfModelChanges. Попробуйте вручную удалить базу данных в SQL Management Studio (или используемом вами инструменте). И снова запустите приложение. Его следует запускать, когда база данных не подготовлена. - person Damb; 14.04.2011
comment
Неплохая идея вызвать base.Seed() в конце этого метода. - person Henk Holterman; 27.05.2013
comment
Небольшое примечание: вам не нужно вызывать context.SaveChanges(); в Seed(), даже если вы пропустите base.Seed(), он сохранится автоматически. - person Full_Int; 31.08.2013
comment
Нет необходимости вызывать base.Seed(), он ничего не делает. Кроме того, как Full_Int сказал выше, нет необходимости вызывать SaveChanges(). Это происходит автоматически после посева. - person Anthony Nichols; 17.01.2016
comment
Я предполагаю, что за 5 лет, прошедших с момента написания этого ответа, в EF произошли некоторые изменения :) Приятно видеть, что они вырезали ненужные (всегда повторяющиеся) фрагменты, такие как context.SaveChanges() - person Damb; 17.01.2016

Вы должны создать собственный инициализатор базы данных, полученный, например, из DropCreateDatabaseIfModelChanges, и заполнить данные в переопределенном методе Seed. Затем вы должны использовать Database.SetInitializer для установки нового инициализатора при запуске приложения. Вот пример (из CTP5), используемый для создания пользовательского индекса в базе данных.

person Ladislav Mrnka    schedule 13.04.2011
comment
поскольку я могу использовать код доступа к файлу только из веб-интерфейса, есть ли способ вызвать инициализатор или вместо этого передать данные? - person Shawn Mclean; 14.04.2011
comment
Вы можете обернуть инициализацию в пользовательский код и передать данные из веб-приложения в этот код, который, в свою очередь, передаст данные в новый экземпляр вашего инициализатора. - person Ladislav Mrnka; 14.04.2011

Пример см. в новой серии руководств по MVC/Entity Framework по адресу http://www.asp.net/entity-framework/tutorials#Using%20MVC И № 1, и № 4 показывают классы инициализатора.

person tdykstra    schedule 13.04.2011