Первое сопоставление кода с представлением базы данных

asp.net code-first entity-framework entity-framework-6

Вопрос

Мне было предложено сопоставить классы ASP.NET Identity с существующей базой данных для операций чтения, используя хранимые процедуры для CRUD. Существует ряд вопросов StackOverflow, в которых указывается, что можно сопоставить представлениям , а также этот вопрос , этот и, наконец, этот .

Я сопоставил классы с представлениями следующим образом:

var applicationUser = modelBuilder.Entity<applicationUser>().HasKey(au => au.Id) //Specify our own View and Stored Procedure names instead of the default tables
    .ToTable("User", "Users").MapToStoredProcedures(sp =>
    {
        sp.Delete(d => d.HasName("spUser_Delete", "Users"));
        sp.Insert(i => i.HasName("spUser_Create", "Users"));
        sp.Delete(u => u.HasName("spUser_Update", "Users"));
    }); 

Где [Пользователи]. [Пользователь] - это представление SQL, получающее данные из таблицы SQL [Users]. [TblUser].

К сожалению, мне пришлось оставить хотя бы один из классов, сопоставленных с таблицей, а не View, поскольку Entity Framework генерирует следующие SQL-

var applicationUser = modelBuilder.Entity<applicationUser>().HasKey(au => au.Id) //Specify our own View and Stored Procedure names instead of the default tables
    .ToTable("User", "Users").MapToStoredProcedures(sp =>
    {
        sp.Delete(d => d.HasName("spUser_Delete", "Users"));
        sp.Insert(i => i.HasName("spUser_Create", "Users"));
        sp.Delete(u => u.HasName("spUser_Update", "Users"));
    }); 

Который возвращает ноль, так как это виды, а не таблицы.

В результате любая попытка использования UserManager приводит к исключению -

Значение не может быть нулевым. Имя параметра: источник

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

Сведения об исключении: System.ArgumentNullException: значение не может быть нулевым. Имя параметра: источник

Ошибка источника:

Строка 48: if (ModelState.IsValid)

Строка 49: {

Строка 50: var userAccount = ожидание UserManager.FindByNameAsync (model.UserName);

Строка 51:

Строка 52: if (userAccount == null)

Ручное изменение запроса на -

var applicationUser = modelBuilder.Entity<applicationUser>().HasKey(au => au.Id) //Specify our own View and Stored Procedure names instead of the default tables
    .ToTable("User", "Users").MapToStoredProcedures(sp =>
    {
        sp.Delete(d => d.HasName("spUser_Delete", "Users"));
        sp.Insert(i => i.HasName("spUser_Create", "Users"));
        sp.Delete(u => u.HasName("spUser_Update", "Users"));
    }); 

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

Есть ли способ убедить Entity Framework удалить требование «Является ли таблица» или утверждать, что таблицы существуют и поэтому вообще пропустить этот шаг?

Изменить: после запроса код для UserManager включен ниже,

AccountController.cs

var applicationUser = modelBuilder.Entity<applicationUser>().HasKey(au => au.Id) //Specify our own View and Stored Procedure names instead of the default tables
    .ToTable("User", "Users").MapToStoredProcedures(sp =>
    {
        sp.Delete(d => d.HasName("spUser_Delete", "Users"));
        sp.Insert(i => i.HasName("spUser_Create", "Users"));
        sp.Delete(u => u.HasName("spUser_Update", "Users"));
    }); 

Принятый ответ

Мне удалось решить эту проблему, создав пользовательский инициализатор базы данных, который заменяет инициализатор по умолчанию CreateDatabaseIfNotExists. Статья Codeguru « Понимание инициализаторов баз данных в коде Entity Framework First» чрезвычайно помогла мне понять, что происходит.

Код для решения -

using System.Data.Entity;

namespace NexGen.Data.Identity
{
    public class IdentityCustomInitializer : IDatabaseInitializer<ApplicationIdentityDbContext>
    {
        public void InitializeDatabase(ApplicationIdentityDbContext)
        {
            return; //Do nothing, database will already have been created using scripts
        }
    }
}

IdentityManager-

using System.Data.Entity;

namespace NexGen.Data.Identity
{
    public class IdentityCustomInitializer : IDatabaseInitializer<ApplicationIdentityDbContext>
    {
        public void InitializeDatabase(ApplicationIdentityDbContext)
        {
            return; //Do nothing, database will already have been created using scripts
        }
    }
}

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


Популярные ответы

Из моего понимания и тестов нет необходимости реализовывать IDatabaseInitializer, имеющий пустой метод InitializeDatabase, такой как pwdst.

Из того, что я увидел в разделе «Понимание инициализаторов баз данных в коде Entity Framework». Во-первых , достаточно позвонить

Database.SetInitializer<ApplicationIdentityDbContext>(null);

когда приложение инициализируется, или, лучше сказать, до того, как впервые будет доступ к базе данных.

Я бы не поместил его внутри ctor моего класса DbContext, чтобы избежать установки инициализатора каждый раз, когда создается экземпляр DbContext . Вместо этого я бы включил его в метод инициализации приложения или в качестве одного из первых операторов метода Main () .

Это отлично работало для моего приложения, используя Entity Framework 6.




Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему