Таблицы созданы, о которых я не просил, что-то не так с моей стратегией инициализации в EF6?

Я использую моделирование в первую очередь кода с Entity Framework 6.2.0. Частично мои требования заключаются в том, чтобы взять на себя полный контроль над всеми аспектами управления базой данных, включая создание, миграцию / обновление и удаление.

Для этого я реализовал собственный инициализатор, например:

public class MyDatabaseInitializer : IDatabaseInitializer<MyDataContext>
{
    public void InitializeDatabase(MyDataContext context)
    {
        if (context.Database.Exists())
            Seed(context);
    }
}

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        System.Data.Entity.Database.SetInitializer(new MyDatabaseInitializer());
    }
}

Если кому-то нужны подробности использования, я могу предоставить больше. Но пока перехожу к проблеме: таблицы создаются в базе данных master, и я не могу понять, почему.

Я не устанавливаю никаких явных подключений к этой базе данных. Я прошел через каждый бит кода запуска, который мог, но никогда не мог уловить его на месте. Я просто получаю таблицы без каких-либо доказательств того, почему. Я даже не могу разглядеть узор. Этого не происходит после определенного звонка или в какой-то конкретный момент запуска, который я вижу. Приложение запускается, и вот они. В окне вывода ничего, никаких исключений, ничего.

Я пытался:

  1. Помещение точки останова в начальную миграцию, где выполняются вызовы CreateTable. В него так и не попали, но таблицы появились в master.
  2. Помещение точек останова в мой класс инициализатора. Никогда не бей.
  3. Добавление вывода Log (окно консоли) в мой контекст. Показывает только то, что я знаю, но никогда не звонит CreateTable.

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

Обновлено:

По предложению я попытался разместить точки останова в конструкторах контекста, но при первом ударе таблицы master уже были созданы. Фактически, на данный момент я уверен, что создание этой таблицы происходит более или менее сразу при запуске приложения и до того, как будет запущен какой-либо из моих кодов запуска. То есть до того, как я создал какие-либо контексты, не говоря уже о возможности их использовать.

Базовый процесс запуска выглядит следующим образом:

App.xaml.cs - OnStartup () устанавливает инициализатор EF (как было предложено, теперь это значение null для целей тестирования)

[Вызывается MainWindow.Show ()]

MainWindow :: OnContentRendered () - вызывает процедуру запуска (статический метод в собственном классе). Существует проверка, чтобы код запуска выполнялся только один раз.

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

В конечном счете, это должно быть какое-то встроенное дело, которое EF хочет сделать самостоятельно. Но я не могу найти способа перехватить или хотя бы проверить то, что он делает. Где-то в самом начале он хочет создавать таблицы, и поскольку единственная известная ему БД - это master, они туда и направляются. Но почему? И что я могу с этим поделать?

Вот как выглядят фабрики контекста и соединений:

using (var context = new MyDataContext(new DbFactory().GetConnectionString())
{
}

public String GetConnectionString(String serverName, String databaseName)
{
    var csb = new SqlConnectionStringBuilder();
    csb.DataSource = serverName;
    csb.InitialCatalog = databaseName;
    csb.ConnectTimeout = DatabaseTimeout;
    csb.PersistSecurityInfo = false;
    csb.IntegratedSecurity = true;
    csb.LoadBalanceTimeout = 0;
    csb.Pooling = true;
    csb.MaxPoolSize = 200;
    csb.MinPoolSize = 0;
    csb.UserInstance = false;
    csb.WorkstationID = AllMaxNetwork.MachineName;
    return csb.ConnectionString;
}

public MyDataContext(String connectionString)
    : base(connectionString) { }

Еще одно обновление: Я доказал две вещи:

  1. Когда эти таблицы создаются, для этого используется начальная миграция. Я изменил длину поля на ненормально большую и увидел, что это изменение отразилось во вновь созданной таблице в master.
  2. Я поместил исключение в начале этой миграции, и создание таблицы остановилось. Однако единственным способом увидеть свидетельство возникновения этого исключения было использование приложения Sysinternals DebugView. Visual Studio 2017 так и не зарегистрировала ни малейшего доказательства того, что это вообще произошло.

К сожалению, мои новые знания только усугубляют загадку. Я до сих пор не понимаю, почему это происходит.

Поместите точку останова в конструктор MyDataContext.

David Browne - Microsoft 24.07.2018 17:06

У вас есть web.config или app.config с подключением к базе данных?

Daniel Gimenez 24.07.2018 17:18

Сначала код, DotNet 4.5.2, WPF. Строка подключения создается по запросу, а не в config.

DonBoitnott 24.07.2018 17:21

@ DavidBrowne-Microsoft Я поставил точку останова в конструкторе контекста, и когда она была достигнута, я проверил базу данных master. Столы уже были на месте.

DonBoitnott 24.07.2018 17:39

Попробуйте добавить context.Database.Initialize(true); для принудительной инициализации. Также проверьте строку подключения на наличие подсказок context.Database.Connection.ConnectionString

Steve Greene 24.07.2018 17:40

@SteveGreene Я не слежу. Поскольку я никогда не знаю, где и когда это происходит, я понятия не имею, что я буду проверять и когда. Что сделает принуждение к Initialize? И я предполагаю тот же вопрос: когда / где я буду это делать?

DonBoitnott 24.07.2018 17:58

Инициализаторы не запускаются, пока вы не используете контекст (установка инициализатора не запускает его), поэтому вызовите проблему, стратегически разместив Initialize в коде запуска, чтобы вызвать проблему.

Steve Greene 24.07.2018 18:07

@SteveGreene Что мне тогда искать? Я до сих пор не понимаю, что это принесет мне пользу. Поскольку мой инициализатор запускается, когда мои контексты установлены. Только не (что я видел), когда этот загадочный экземпляр происходит для создания таблиц master.

DonBoitnott 24.07.2018 18:46

Итак, созданные таблицы являются таблицами приложений из вашего контекста, но они попадают в master вместо предполагаемой базы данных? Инициализатор не должен запускаться, пока вы не используете контекст или принудительную инициализацию. Я бы заподозрил строку подключения или, возможно, настройки конфигурации. Профилировщик SQL может помочь. Вы говорите, что создаете строку подключения по запросу - уверены ли вы, что она используется? Жестко закодируйте один в конструктор контекста в качестве теста.

Steve Greene 24.07.2018 20:26

@SteveGreene Верно, они попадают в master. Все строки подключения создаются по запросу для каждого создаваемого контекста. Мы имеем дело с несколькими базами данных и при необходимости предоставляем разные строки для каждой из них. Я наблюдал как за фабрикой, так и за контекстными ctors, но я не вижу ни строки подключения, ни context.Database, использующего master в качестве своей БД. Боюсь, что все, что происходит внизу, делается самим EF, и я не могу установить на нем точку останова.

DonBoitnott 24.07.2018 20:33

@SteveGreene Позвольте мне немного расширить для ясности: вы сказали «предполагаемая база данных». Это не совсем так. С моей стороны нет никакого намерения. Все, что происходит, выходит за рамки обычного потока моей последовательности запуска. Каждая часть того, что делает ожидайте, что произойдет. Это что-то совершенно другое, где полный набор таблиц создается в master, но не из-за чего-то, что я намеренно пытался. Я вообще не могу сказать, что вызывает действие.

DonBoitnott 24.07.2018 20:45

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

Steve Greene 24.07.2018 21:14

Установите значение null, все равно создает. Единственный файл конфигурации - это App.config в проекте EXE. Все, что в нем есть, - это раздел <entityFramework> с <provider> для клиента Sql.

DonBoitnott 24.07.2018 22:02

@DonBoitnott - единственный способ, чтобы таблицы оказались в master, - это если вы подключитесь к master. Как выглядит ваша строка подключения? Готов поспорить, что он содержит запись Initial Catalog=master; или вообще не содержит записи Initial Catalog, и в этом случае будет использоваться база данных ваш аккаунт по умолчанию. Эта база данных определяется при создании учетной записи. Если вы подключаетесь как sa или используете учетную запись администратора баз данных Windows, по умолчанию, вероятно, будет master.

Panagiotis Kanavos 25.07.2018 13:44

@PanagiotisKanavos Я все время слышу это предложение ... но какая строка подключения? Мой файл конфигурации не содержит его, и у моего кода нет возможности его создать. Поэтому я понятия не имею, о какой строке подключения все говорят. Я понятия не имею, где бы я увидел что-то, что EF, похоже, извлекает за кулисами, и все это само по себе.

DonBoitnott 25.07.2018 13:45

@DonBoitnott, ваш конфигурационный файл делает содержит его, иначе он не будет подключаться ни к какой базе данных - какой именно? На какой машине? EF ничего не делает за кулисами

Panagiotis Kanavos 25.07.2018 13:50

@DonBoitnott, как вы сказали ранее All connection strings are made on-demand for every context that is created. We deal with multiple databases. Где эти строки подключения? На что они похожи? Какие столы все равно генерируются, как их зовут?

Panagiotis Kanavos 25.07.2018 13:53

@DonBoitnott в вашем методе InitializeDatabase, когда вы вызываете context.Database.Exists(), как выглядит строка подключения для Database? Как выглядит ваш сценарий миграции?

Panagiotis Kanavos 25.07.2018 13:55

Я добавил примеры соответствующих штук. Строка подключения выглядит так, как я ожидал. Ни в одном из них нет master. Все таблицы создаются, каждая таблица, которую я ожидал бы в одной из своих баз данных, не имеет значения. И метод InitializeDatabase сейчас тоже неактуален, как я уже сказал ... в игре нет инициализатора, он установлен null.

DonBoitnott 25.07.2018 14:02

@PanagiotisKanavos Ваш комментарий о «базе данных по умолчанию» интригует. Предположим, что, поскольку я не предоставляю строку подключения по умолчанию, она создается для меня и что она использует master в качестве своей базы данных. Настоящий вопрос по-прежнему «почему». Почему он это делает? Что делает EF, если он ей вообще нужен? Что мне сделать, чтобы это остановить или хотя бы увидеть? Если я не смогу понять, почему это вообще происходит, тогда все это чисто академическое.

DonBoitnott 25.07.2018 14:26
Какие столы ты о чем? Если вы используете sql server, да, в базе данных master всегда будет несколько таблиц. Как говорится, здесь: SQL Server использует основную базу данных для записи всей информации о системе экземпляра SQL Server, такой как учетные записи, конечные точки, связанные серверы и параметры конфигурации. ... Это не имеет ничего общего с EF.
AsheraH 25.07.2018 14:32

@AsheraH Мои столы. Таблицы я определил.

DonBoitnott 25.07.2018 14:33
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
22
68
0

Другие вопросы по теме