Code First Mapping to Database Views

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

Question

I've been asked to use stored procedures for CRUD to map the ASP.NET Identity classes to existing database views for read operations. Several StackOverflow questions claim that can be mapped to views, as well as this inquiry, like as, and finally like as.

The classes and views are mapped as follows:

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"));
    }); 

In which [Users]. A SQL view named [User] retrieves information from the SQL table named [Users]. [tblUser].

Unfortunately, Entity Framework generates the following SQL, thus I had to leave at least one of the classes assigned to a table rather than a view.

SELECT Count(*)
FROM INFORMATION_SCHEMA.TABLES AS t
WHERE t.TABLE_TYPE = 'BASE TABLE'
    AND (t.TABLE_SCHEMA + '.' + t.TABLE_NAME IN ('Users.ApplicationRole','Users.User','Users.AuthenticationToken','Users.UserClaim','Users.UserLogin','Users.UserRole','Users.Department','Users.PasswordResetToken','Users.UserDepartment')
        OR t.TABLE_NAME = 'EdmMetadata')
go

This, because these are views rather than tables, returns zero.

As a result, whenever the UserManager is used, the following exception is raised:

Value cannot be null. Parameter name: source

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.ArgumentNullException: Value cannot be null. Parameter name: source

Source Error:

Line 48: if (ModelState.IsValid)

Line 49: {

Line 50: var userAccount = await UserManager.FindByNameAsync(model.UserName);

Line 51:

Line 52: if (userAccount == null)

Changing the query manually to-

SELECT Count(*)
FROM INFORMATION_SCHEMA.TABLES AS t
WHERE (t.TABLE_SCHEMA + '.' + t.TABLE_NAME IN ('Users.ApplicationRole','Users.User','Users.AuthenticationToken','Users.UserClaim','Users.UserLogin','Users.UserRole','Users.Department','Users.PasswordResetToken','Users.UserDepartment')
        OR t.TABLE_NAME = 'EdmMetadata')
go

gives back the right nine Views and presumably wouldn't lead to the issue. It only needs one of the classes to be mapped to a table for it to believe the database is accurate and continue operating normally.

Can I convince Entity Framework to drop the "Is a table" criterion or claim that the tables already exist and omit this step entirely?

Edit: The code for the UserManager is provided below in response to a request:

AccountController.cs

[Authorize]
public class AccountController : Controller
{
    public AccountController()
        : this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationIdentityDbContext())))
    {

    }

    public AccountController(UserManager<ApplicationUser> userManager)
    {
        UserManager = userManager;
    }

    public UserManager<ApplicationUser> UserManager { get; private set; }
1
2
5/23/2017 12:19:14 PM

Accepted Answer

ZZZ_tmp
2
12/4/2013 9:50:54 AM

Popular Answer

According to my observations and experiments, it is unnecessary to implement a IDatabaseInitializer with an empty InitializeDatabase method, as pwdst did.

I was at Understanding Entity Framework Code First's Database Initializers, and what I saw is enough to call

Database.SetInitializer<ApplicationIdentityDbContext>(null);

when the application is initializing, or more precisely, before the database is accessed for the first time.

To prevent having to set the initializer each time a DbContext instance is created, I wouldn't place it inside the ctor of my DbContext class. Instead, I would include it in the initialization method for the program or as one of the function's first statements (Main()).

This was successful for my Entity Framework 6 application.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow