У меня есть модели, основанные на EF Code First, и я хочу использовать их с по умолчанию MembershipProvider, но я не знаю, как правильно писать модель, поэтому она не будет удалять все мои данные при воссоздании таблиц, когда были внесены изменения в модель.
Как использовать провайдера членства с EF Code First?
Ответ 1
В настоящее время (EF 4.1 CTP) EF Code First не имеет этого параметра. Он всегда отбрасывает таблицу, если вы вносили изменения в модель.
Update:
EF 4.1 RTM позволяет создать пользовательский инициализатор базы данных и указать создание объектов db и выборки данных.
Ответ 2
Посмотрите на этот проект
http://codefirstmembership.codeplex.com/
Он имеет классы сущностей для пользователей и ролей, а также реализацию roleprovider и membershipprovider. Если вы включите пользователей и роли в свой класс datacontext, таблицы будут созданы в вашей базе данных.
Ответ 3
Ваш вопрос состоит из двух частей.
- Как использовать API членства asp.net с EF-кодом?
- Как сохранить существующие данные при изменении модели?
Как сохранить существующие данные при изменении модели, поскольку с EF 4.0/asp.net mvc 3 миграция базы данных еще не поддерживается. Вам нужно будет перейти к asp.net mvc 4.0/EF 4.3, где поддерживаются миграции баз данных или используются аналогичные альтернативы, но его бета-версия.
миграция базы данных asp.net mvc 4.0 в блоге scott gu
Теперь перейдем к вопросу о том, как использовать провайдера членства asp.net с кодом EF. Есть несколько проблем:
-
Мы не можем/не должны присоединяться к таблицам поставщиков членства asp.net. Его не рекомендуется, поэтому мое предложение будет заключаться в создании "класса адаптера" для классов поставщика членства asp.net. Для примера:
public class UserAdapter { // all user related attributes. Not stored in membership schema, but your schema public string UserProxyName; // some attributes stored in membership schema [NotMapped] public string Email { get { Membership.GetUser(UserProxyName).Email; } } // some attributes stored in membership schema and not in your schema [NotMapped] public string[] UserRoles { get { return Roles.GetRolesForUser(UserProxyName); } } }
Теперь для обновления информации вы можете написать некоторые функции в самой модели, однако я бы предложил создать UserRepository с шаблоном проектирования репозитория для обработки пользовательских CRUD-операций.
-
Вторая задача - создать базу данных при первом запуске. Поскольку посев становится проблемой, если вы хотите засеять информацию о пользователе, тогда отдельно выполняемый aspnet_regsql неэффективен, поскольку ожидается, что схема членства будет ожидаться до того, как произойдет посев. Я наткнулся на эту приятную статью, с некоторой тонкой настройкой она работала для меня:
Ответ 4
Если вы используете SQL Server, проверьте следующее:
http://www.paragm.com/ef-v4-1-code-first-and-asp-net-membership-service/
Ответ 5
Существует также моя библиотека, которая в основном позволяет вам определить, как должно быть настроено почти все, включая: тип ключа, где находится ваш объект контекста, и где находятся ваши объекты пользователя/роли. Расширяется с использованием абстрактных базовых классов или интерфейсов. Также работает довольно хорошо из коробки с шаблоном хранилища/единицей работы/контейнерами IoC.
Ответ 6
В моем файле DbContext.cs у меня есть функция Seed, где я вызываю ApplicationServices.InstallServices()
для установки членства ASP.NET в мою базу данных. Теперь каждый раз, когда мой инициализатор удаляет базу данных, он снова воссоздает схему членства ASP.NET.
public class PanelInitializer : DropCreateDatabaseAlways<PanelContext>
{
protected override void Seed(PanelContext context)
{
//Install ASP.NET Membership
ApplicationServices.InstallServices(SqlFeatures.Membership | SqlFeatures.RoleManager);
new List<Panel>
{
Класс ApplicationServices
using System.Configuration;
using System.Data.SqlClient;
using System.Web.Management;
namespace Lansw.Panels.DataAccess.Contexts
{
public class ApplicationServices
{
readonly static string DefaultConnectionString = ConfigurationManager.AppSettings["DefaultConnectionString"];
readonly static string ConnectionString = ConfigurationManager.ConnectionStrings[DefaultConnectionString].ConnectionString;
readonly static SqlConnectionStringBuilder MyBuilder = new SqlConnectionStringBuilder(ConnectionString);
public static void InstallServices(SqlFeatures sqlFeatures)
{
SqlServices.Install(MyBuilder.InitialCatalog, sqlFeatures, ConnectionString);
}
public static void UninstallServices(SqlFeatures sqlFeatures)
{
SqlServices.Uninstall(MyBuilder.InitialCatalog, sqlFeatures, ConnectionString);
}
}
}
Благодаря @ImarSpaanjaars http://imar.spaanjaars.com/563/using-entity-framework-code-first-and-aspnet-membership-together.