Проект интернет-приложения MVC4 по умолчанию путает многих людей. 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 и явно убедиться, что все являются одной и той же страницей в отношении того, какое соединение с базой данных следует использовать. Ваш AccountsContext
теперь, по сути, ориентирован на базу данных, поэтому он не заставит EF создать базу данных или попытаться выполнить какие-либо миграции - для этого и предназначен MyAppContext
. Вы можете создать другие контексты так же, как AccountsContext
, чтобы разбить функциональность вашего приложения; вам просто нужно отразить любые объявления свойств DbSet
в вашем «основном» контексте.
Джули Лерман в своей книге Programming называет эту концепцию "ограниченными контекстами". Entity Framework: DbContext, и представляет универсальный класс, от которого вы можете наследовать все свои "ограниченные контексты", поэтому вам не нужно каждый раз указывать имя строки подключения и задавать инициализатору базы данных значение null.
person
Chris Pratt
schedule
15.04.2013