1

Я работаю над приложением MVC4, которое использует Entity Framework 5, миграции баз данных и app-членство api. В моей среде разработки я могу полностью удалить свою базу данных, запустить пакет (.zip), обновить страницу, и все работает так, как ожидалось; создается база данных, вызывается метод seed и некоторые значения по умолчанию застревают в базе данных.Переходы базы данных EF

Отлично, очень просто! Но ..... да, всегда есть но!

Когда я иду развернуть этот же пакет (только изменил строку подключения db) и запустил это в удаленной среде, поведение изменится. Опять же, если я полностью войду и удалю базу данных, запустите пакет (.zip), обновите страницу, база данных будет создана только с помощью api-таблиц asp. Я проверил строку подключения, и это точно, а не причина, или таблицы базы данных и членства не могли быть созданы.

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

Есть ли у кого-нибудь предложения? Может ли это быть побочным эффектом истории смешанной миграции?

Заранее благодарен!

+0

У вас есть две строки подключения? Для членства и один для вашей заявки? – Floremin

+0

Хорошая мысль, но нет, только 1. Я использую преобразования при создании пакета, так что, может быть, что-то погребенное там не правильно? –

ответ

4

Проект MVC4 Internet Application по умолчанию запутывает множество людей. Microsoft хотела продемонстрировать функциональность SimpleMembership, которая требует контекста EF, но не является здравым смыслом, что вы должны фактически изменить эту часть, чтобы эффективно использовать остальную часть вашего приложения.

Итак, небольшое руководство по работе с Entity Framework поможет понять, почему это происходит, я думаю.

Entity Framework (по крайней мере, версия 5, может изменяться в 6 или последующих версиях) позволяет использовать только один DbContext для вашего приложения. Скорее всего, у вас есть как минимум два файла: AccountsContext, который был автогенерирован шаблоном проекта и контекстом, который вы используете для остальной части вашего приложения. Если бы вы отключили автоматическую миграцию и попытались сгенерировать миграцию, EF предупредил вас, что вам нужно указать, какой контекст использовать. Тем не менее, автоматическая миграция по умолчанию используется в Code First, очень немногие отключают это, и, таким образом, очень немногие когда-либо получают предупреждение.

Когда автоматическая миграция включена и у вас нет существующей базы данных, EF с радостью (и молча) создает базу данных для вас из вашего контекста. Но что, если у вас несколько контекстов? Ну, другая неприятная маленькая особенность EF заключается в том, что она создает базу данных точно в срок. Итак, какой контекст используется, это функция, с которой в первую очередь осуществляется доступ. Приятно, да? Итак, если вы пытаетесь сделать что-либо вроде входа в систему, база данных создается из AccountsContext, а затем, когда вы пытаетесь получить доступ к чему-либо из контекста вашего приложения, база данных уже существует, а EF делает ничего.

Итак, что с этим делать? Ну, вам нужно один контекст для устранения двусмысленности. У вас все еще может быть несколько контекстов, если вы хотите в своем приложении, но вы должны по существу сказать EF, что во всех других контекстах есть база данных - сначала, то есть ничего не делайте.

public class AccountsContext : DbContext 
{ 
    public AccountsContext() 
     : base("name=YourConnectionStringName") 
    { 
     Database.SetInitializer<AccountsContext>(null); 
    } 

    ... 
} 

public class MyAppContext : DbContext 
{ 
    public MyAppContext() 
     : base("name=YourConnectionStringName") 
    { 
    } 

    // All your entities here, including stuff from AccountsContext 

} 

MyAppContext будет ваш «мастер» контекст, который будет иметь каждый объект в базе данных, что EF должен знать. Вызов base служит для того, чтобы угадывать EF с пути и явно следить за тем, чтобы все были одной и той же страницей относительно того, какое соединение с базой данных должно использоваться.Ваш теперь по сути является базой данных, поэтому он не будет заставлять EF создавать базу данных или пытаться выполнить какие-либо миграции - вот что такое MyAppContext. Вы можете создавать другие контексты так же, как AccountsContext, чтобы разбить функциональность вашего приложения; вам просто нужно отразить любые объявления объявлений DbSet в вашем «главном» контексте.

Julie Lehrman называет эту концепцию «ограниченными контекстами» в своей книге Programming Entity Framework: DbContext и представляет общий класс, на который вы можете наследовать все ваши «ограниченные контексты», поэтому вам не нужно указывать имя строки подключения и задавать инициализатор базы данных до нуля каждый раз.

+0

спасибо за ответ. Я добавил вызов, чтобы сначала создать контекст db для учетных записей, но почему это нормально работает в одной среде, а не в другом? Надеюсь, у меня будет шанс проверить это изменение на этой неделе и последует тогда –

+0

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

+0

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

Смежные вопросы