Я использую моделирование в первую очередь кода с 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, и я не могу понять, почему.
Я не устанавливаю никаких явных подключений к этой базе данных. Я прошел через каждый бит кода запуска, который мог, но никогда не мог уловить его на месте. Я просто получаю таблицы без каких-либо доказательств того, почему. Я даже не могу разглядеть узор. Этого не происходит после определенного звонка или в какой-то конкретный момент запуска, который я вижу. Приложение запускается, и вот они. В окне вывода ничего, никаких исключений, ничего.
Я пытался:
CreateTable. В него так и не попали, но таблицы появились в master.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) { }
Еще одно обновление: Я доказал две вещи:
master.К сожалению, мои новые знания только усугубляют загадку. Я до сих пор не понимаю, почему это происходит.
У вас есть web.config или app.config с подключением к базе данных?
Сначала код, DotNet 4.5.2, WPF. Строка подключения создается по запросу, а не в config.
@ DavidBrowne-Microsoft Я поставил точку останова в конструкторе контекста, и когда она была достигнута, я проверил базу данных master. Столы уже были на месте.
Попробуйте добавить context.Database.Initialize(true); для принудительной инициализации. Также проверьте строку подключения на наличие подсказок context.Database.Connection.ConnectionString
@SteveGreene Я не слежу. Поскольку я никогда не знаю, где и когда это происходит, я понятия не имею, что я буду проверять и когда. Что сделает принуждение к Initialize? И я предполагаю тот же вопрос: когда / где я буду это делать?
Инициализаторы не запускаются, пока вы не используете контекст (установка инициализатора не запускает его), поэтому вызовите проблему, стратегически разместив Initialize в коде запуска, чтобы вызвать проблему.
@SteveGreene Что мне тогда искать? Я до сих пор не понимаю, что это принесет мне пользу. Поскольку мой инициализатор запускается, когда мои контексты установлены. Только не (что я видел), когда этот загадочный экземпляр происходит для создания таблиц master.
Итак, созданные таблицы являются таблицами приложений из вашего контекста, но они попадают в master вместо предполагаемой базы данных? Инициализатор не должен запускаться, пока вы не используете контекст или принудительную инициализацию. Я бы заподозрил строку подключения или, возможно, настройки конфигурации. Профилировщик SQL может помочь. Вы говорите, что создаете строку подключения по запросу - уверены ли вы, что она используется? Жестко закодируйте один в конструктор контекста в качестве теста.
@SteveGreene Верно, они попадают в master. Все строки подключения создаются по запросу для каждого создаваемого контекста. Мы имеем дело с несколькими базами данных и при необходимости предоставляем разные строки для каждой из них. Я наблюдал как за фабрикой, так и за контекстными ctors, но я не вижу ни строки подключения, ни context.Database, использующего master в качестве своей БД. Боюсь, что все, что происходит внизу, делается самим EF, и я не могу установить на нем точку останова.
@SteveGreene Позвольте мне немного расширить для ясности: вы сказали «предполагаемая база данных». Это не совсем так. С моей стороны нет никакого намерения. Все, что происходит, выходит за рамки обычного потока моей последовательности запуска. Каждая часть того, что делает ожидайте, что произойдет. Это что-то совершенно другое, где полный набор таблиц создается в master, но не из-за чего-то, что я намеренно пытался. Я вообще не могу сказать, что вызывает действие.
Первым делом я бы попробовал установить инициализатор на ноль. Если что-то все еще меняется, это ищется в вашем конфигурационном файле.
Установите значение null, все равно создает. Единственный файл конфигурации - это App.config в проекте EXE. Все, что в нем есть, - это раздел <entityFramework> с <provider> для клиента Sql.
@DonBoitnott - единственный способ, чтобы таблицы оказались в master, - это если вы подключитесь к master. Как выглядит ваша строка подключения? Готов поспорить, что он содержит запись Initial Catalog=master; или вообще не содержит записи Initial Catalog, и в этом случае будет использоваться база данных ваш аккаунт по умолчанию. Эта база данных определяется при создании учетной записи. Если вы подключаетесь как sa или используете учетную запись администратора баз данных Windows, по умолчанию, вероятно, будет master.
@PanagiotisKanavos Я все время слышу это предложение ... но какая строка подключения? Мой файл конфигурации не содержит его, и у моего кода нет возможности его создать. Поэтому я понятия не имею, о какой строке подключения все говорят. Я понятия не имею, где бы я увидел что-то, что EF, похоже, извлекает за кулисами, и все это само по себе.
@DonBoitnott, ваш конфигурационный файл делает содержит его, иначе он не будет подключаться ни к какой базе данных - какой именно? На какой машине? EF ничего не делает за кулисами
@DonBoitnott, как вы сказали ранее All connection strings are made on-demand for every context that is created. We deal with multiple databases. Где эти строки подключения? На что они похожи? Какие столы все равно генерируются, как их зовут?
@DonBoitnott в вашем методе InitializeDatabase, когда вы вызываете context.Database.Exists(), как выглядит строка подключения для Database? Как выглядит ваш сценарий миграции?
Я добавил примеры соответствующих штук. Строка подключения выглядит так, как я ожидал. Ни в одном из них нет master. Все таблицы создаются, каждая таблица, которую я ожидал бы в одной из своих баз данных, не имеет значения. И метод InitializeDatabase сейчас тоже неактуален, как я уже сказал ... в игре нет инициализатора, он установлен null.
@PanagiotisKanavos Ваш комментарий о «базе данных по умолчанию» интригует. Предположим, что, поскольку я не предоставляю строку подключения по умолчанию, она создается для меня и что она использует master в качестве своей базы данных. Настоящий вопрос по-прежнему «почему». Почему он это делает? Что делает EF, если он ей вообще нужен? Что мне сделать, чтобы это остановить или хотя бы увидеть? Если я не смогу понять, почему это вообще происходит, тогда все это чисто академическое.
@AsheraH Мои столы. Таблицы я определил.





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