2015-06-03 4 views
1

Я создал простое консольное приложение, установил EntityFramework из nuget и выполнил команду Enable-Migrations.Entity Framework Migrations: Constructor Configuration всегда всегда

Вот код основной:

using(var ctx = new AppDbContext()) 
{ 
    var persons = ctx.Persons.ToList(); 
    Console.ReadKey(); 
} 

Вот код класса конфигурации

internal sealed class Configuration : DbMigrationsConfiguration<AppDbContext> 
{ 
    public Configuration() 
    { 
     AutomaticMigrationsEnabled = true; 
     Console.WriteLine("Configuration: Constructor"); 
    } 

    protected override void Seed(AppDbContext context) 
    { 
     Console.WriteLine("Configuration: Seed"); 
    } 
} 

Вот рамки сущность часть в app.config:

<entityFramework> 
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework"> 
    <parameters> 
     <parameter value="mssqllocaldb" /> 
    </parameters> 
    </defaultConnectionFactory> 
    <providers> 
    <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> 
    </providers> 
</entityFramework> 

Если я запустил консольное приложение, то строится конструктор класса Configuration of Migrations. Зачем? Я не изменяю инициализатор базы данных.

Update

Я попытался теперь некоторые инициализаторы базы данных и посмотреть, если конструктор класса конфигурации называется. Вот мой результат:

public class AppDbContext : DbContext 
{ 
    static AppDbContext() 
    { 
     //Database.SetInitializer<AppDbContext>(new CreateDatabaseIfNotExists<AppDbContext>()); 
     // ==> Configuration class constructor called 

     //Database.SetInitializer<AppDbContext>(new DropCreateDatabaseIfModelChanges<AppDbContext>()); 
     // ==> Configuration class constructor called 

     //Database.SetInitializer<AppDbContext>(new DropCreateDatabaseAlways<AppDbContext>()); 
     // ==> Configuration class constructor called 

     Database.SetInitializer<AppDbContext>(null); 
     // ==> Configuration class constructor is NOT called 
    } 

    public IDbSet<Person> Persons { get; set; } 
} 

Я устанавливаю инициализатор базы данных явно, но вызывается конструктор класса конфигурации. Странное поведение.

+0

У вас включена автоматическая миграция? Вы получаете сообщение об ошибке? Возможно, вам нужно увидеть свой контекстный класс. –

+0

Итак, вы говорите, что вы не используете Database.SetInitializers в любом месте? – Ruskin

+0

Да, я не устанавливаю инициализатор базы данных, а не в app.config, а не в коде. – malt

ответ

1

Как вы упомянули, вы выполнили команду Enable-Migrations. Итак, что же делает, добавив новый класс конфигурации миграции. Этот класс будет применять изменения конфигурации, указанные в классе, связанном с миграциями, при запуске приложения.

DatabaseInitializers - это стратегии применения миграции, даже если вы их не тронули, но объект класса Configuration будет создан.

Update:

Если вы не делаете это в вашем коде, то посмотрите на файл конфигурации приложения. Это может иметь что-то, что выглядит как:

<contexts> 
     <context type="AppDbContext, MyAssembly"> 
     <databaseInitializer 
type="System.Data.Entity.MigrateDatabaseToLatestVersion`2[[AppDbContext, MyAssembly], 
          [Migrations.Configuration, MyAssembly]], EntityFramework" /> 


</context> 

Для получения более подробной информации см это documentation.

Update 2:

Я думаю, я нашел ответ. Когда вы заглянули в код EntityFramework, ясно видно, что databaseInitializer запускается, когда ваш первый запрос linq становится понятным. См. Стек вызовов ниже захваченного при отладке приложения.

Screenshot of Callstack from with in the configuration constructor

Случай 1: Когда вы используете Database.SetInitializer<AppDbContext>(null);, которые на самом деле создать NullDatabaseInitializer<TContext>() как инициализатор по умолчанию, который ничего не делает, поэтому конфигурация не была вызвана.

Дело 2: Когда вы удаляете строку Database.SetInitializer<AppDbContext>(null);, тогда все началось с использования значений по умолчанию для поставщиков.В этом случае внешняя спецификация DatabaseInitializer не предусмотрена, поэтому EF получит инициализатор по умолчанию, который в этом случае равен CreateIfNotExist<AppDbContext>. Инициализатор затем попытается найти конфигурацию, и, конечно, у него есть класс конфигурации, поэтому будет создан экземпляр класса Configuration, и будет вызываться конструктор.

Хотя мне потребовалось пару часов, чтобы понять это.

+0

Я не изменил инициализатор базы данных, поэтому MigrateDatabaseToLatestVersion <..> не используется. Но конструктор класса Configuration выполняется, но я не понимаю, почему этот конструктор вызывается. Почему это необходимо? Если я добавлю второй класс Configuration2, конструкторы Configuration и Configuration2 не будут выполнены. Что это за логика? – malt

+0

См. Мой обновленный ответ. Я добавил подробности о том, что еще может быть ответственным за настройку конфигурации миграции. – vendettamit

+0

Thx, но я не меняю конфигурационный файл. Я не устанавливаю инициализатор через файл конфигурации. Я попробовал много разных инициализаторов. См. Оригинальные публикации результатов ... Очень интересно. – malt