新的ASP.NET MVC 5应用程序如何知道如何创建数据库以及Account Controller如何访问数据库?

34 asp.net asp.net-mvc entity-framework asp.net-mvc-5 asp.net-identity

我使用Visual Studio 2013 Update 2创建了一个ASP.NET MVC 5应用程序.在应用程序中,我有一个帐户控制器.它与我习惯的不同,并且不包含dbcontext的实例化.

public class AccountController : Controller
{
    private ApplicationUserManager _userManager;

    public AccountController()
    {
    }

    public AccountController(ApplicationUserManager userManager)
    {
        UserManager = userManager;
    }

    public ApplicationUserManager UserManager {
        get
        {
            return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
        }
        private set
        {
            _userManager = value;
        }
    }
Run Code Online (Sandbox Code Playgroud)

web.config默认创建的是一个像这样的连接字符串:

  <connectionStrings>
    <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-WebApplication3-20140417072624.mdf;Initial Catalog=aspnet-WebApplication3-20140417072624;Integrated Security=True"
      providerName="System.Data.SqlClient" />
  </connectionStrings>
Run Code Online (Sandbox Code Playgroud)

有人可以向我解释当应用程序第一次启动时应用程序如何知道为此应用程序创建数据库吗?

此外,在后续启动时,它是否使用Entity Framework访问Identity表来进行身份验证?

Dav*_*ich 78

1)这里有什么:

当您创建新的MVC 5应用程序并选择" 个人用户帐户 "时,会包含一个新的ASP.NET身份提供程序,它使用Entity Framework 6 Code-First.

Microsoft已采用EF-Code-First使Identity尽可能可自定义.

首次访问Identity时,Entity Framework会检查数据库是否存在.除非另有配置,否则它使用"DefaultConnection"查找身份数据库.如果在调用Identity时数据库不存在,则EF会自动创建数据库.

注意你的连接字符串包含

`AttachDbFilename=|DataDirectory|\aspnet-WebApplication3-20140417072624.mdf`
Run Code Online (Sandbox Code Playgroud)

如果您打开App_Data文件夹,则应该有一个aspnet-WebApplication3-20140417072624.mdf文件.

如果双击此.mdf文件,VS2013 Server Explorer将打开您的数据库.如果您已尝试访问任何标识功能,则将创建以下表:

  • _MigrationHistory
  • ASPNetRoles
  • ASPNetUserClaims
  • ASPNetUserLogins
  • ASPNetUsers

默认情况下,您的应用程序配置为使用SQL Server Compact(MDF文件),因此您不必运行实际的SQL Server实例.所有这些都是可定制的.MDF文件的名称,标识数据库的模式,SQL Compact与实际SQL Server实例的选择.更改您的连接字符串,或创建一个新的连接字符串并将此新连接传递给您的上下文.


2)我的上下文是什么?

所有这一切都很好,但您提出的一个重要问题基本上是"我的上下文在哪里? ",以及关于如何进一步定制数据库或更改验证逻辑的相关隐含问题.

您会注意到您的项目引用Microsoft.AspNet.Identity.EntityFramework.该程序集是Class 的实现IdentityDBContext<TUser>和实现UserManager.

打开你的AccountController,注意构造函数已经UserManager传递了new UserStore对象,而对象又传递了一个对象,传递给它ApplicationDbContext.

    public AccountController()
        : this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))
Run Code Online (Sandbox Code Playgroud)

ApplicationDbContext在您的模型文件夹中定义.在该文件夹中,您将找到IdentityModels.cs文件.打开它,你会看到

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("DefaultConnection")
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

这是您的身份上下文被分配的位置.您可以更改传递给ApplicationDbContext构造函数的连接名称,或在帐户控制器中定义和使用不同的上下文.


3)我如何定制我的身份模式?

IdentityModels.cs文件中定义的另一个类是从ApplicationUser类继承的IdentityUser类.

public class ApplicationUser : IdentityUser
{
}
Run Code Online (Sandbox Code Playgroud)

您添加到此类的任何属性都将保留ASPNetUsers表中.模式的其余部分在IdentityDbContext类中定义.因此,通过向Context Context添加DBSet,您可以向Identity Schema添加更多表(例如Privileges),

public DBSet<Privileges> { get; set; }
Run Code Online (Sandbox Code Playgroud)

改变其他表格(角色,索赔等)也是可能的,但涉及的更多.例如,要自定义Roles表,您必须通过覆盖Context 的方法来实现NewIdentityRole继承IdentityRole并添加它的关系OnModelCreating().

这篇关于自定义角色表的文章很好地描述了所涉及的步骤.即使在这里,您会发现只需添加新列就会遇到很大的麻烦.从IdentityDbContext类中创建的原始模式中删除表或列可能与创建自己的IdentityDbContext类实现一样麻烦.

  • 我刚刚查看了RC更新2提供的内容,我想我会暂时远离它.据我所知,帐户控制器似乎没有完成.他们在帐户控制器上做了很多更改,但似乎缺少登录方法,当我启动相同的应用程序时,没有"登录"或"注册"链接点击.似乎RC是一个WIP :-(将接受你的答案,因为它适用于大多数人正在使用的.谢谢 (4认同)