【问题标题】:Replacing automatically created ApplicationDbContext替换自动创建的 ApplicationDbContext
【发布时间】:2023-03-17 05:00:01
【问题描述】:

我应该以免责声明开头,说我是 ASP.NET 开发的新手,并不真正了解数据库上下文,尽管我花了最后一个小时阅读文档。当我构建我的 ASP.NET MVC 5 应用程序时,我选择了个人用户帐户身份验证。 Visual Studio 创建了一个名为IdentityModels.cs 的文件,并在其中定义了一个ApplicationUser 类和一个ApplicationDbContext 类。

我已经完成了一些开发工作,并且我的 CRUD 控制器使用 ApplicationDbContext 与数据库通信,方法是在每个控制器上都有这个私有属性:

private ApplicationDbContext db = new ApplicationDbContext();

在控制器操作中,我会执行以下操作:

return View(db.Trains.ToList());

我想整理一下这个数据库上下文的东西,但我需要先了解它。我的主要问题是:

  1. 是否可以像我现在这样对整个应用程序只使用一个数据库上下文?
  2. 我可以用我自己的替换IdentityModels.cs 中定义的ApplicationDbContext 类吗?
  3. ApplicationDbContext 类派生自 IdentityDbContext<ApplicationUser>,这是否意味着我应该为 Visual Studio 提供的用户身份验证内容和我自己的代码拥有单独的数据库上下文?

我认为我的最终目标是使用我自己的数据库上下文,称为DatabaseContext,然后在我的所有控制器继承的基本控制器中使用它。然后我只有一个实例化数据库上下文的地方,而不是在每个控制器中。

谁知道呢,我可能想错了。每个人似乎都有自己喜欢的处理方式。

谢谢!

【问题讨论】:

    标签: c# asp.net asp.net-mvc entity-framework


    【解决方案1】:

    是否可以像我现在所做的那样为我的整个应用程序只使用一个数据库上下文?

    • 如果您决定直接从 UI 层访问 DB(这是一个单独的讨论),那没关系,因为 ApplicationDbContext 是您的控制器的私有字段,并且控制器是根据请求创建和处置的- ApplicationDbContext 将根据请求创建和处理。

    我可以用我自己的替换 IdentityModels.cs 中定义的 ApplicationDbContext 类吗?

    • 你绝对可以做到。它用于创建一个UserStore,它接收DbContext 作为构造函数中的参数,所以这个

    var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(new CustomDbContext("connection")));

    会起作用。您仍然必须确保 ApplicationUser 是您自定义上下文中的实体。当然你也可以覆盖/替换ApplicationUser

    ApplicationDbContext 类派生自 IdentityDbContext,这是否意味着我应该拥有 为我提供的用户身份验证内容提供单独的数据库上下文 通过 Visual Studio 和我自己的代码?

    默认情况下,Asp.Net Identity 会为您生成一个新数据库,ApplicationDbContext 配置为使用此数据库。您也可以将身份验证相关实体存储在任何其他数据库中,您只需要确保所有相关表都在那里。您还可以扩展此数据库以包含您在应用程序中使用的其他表,以便您可以全部使用相同的上下文。

    P.S: ApplicationDbContext 不必实现 IdentityDbContext<ApplicationUser>,扩展默认 DbContext 也可以(如果您已经生成了 Db,则必须更新它\使用代码迁移以使以下工作):

     public class ApplicationDbContext : DbContext 
      {
         public ApplicationDbContext()
             : base("DefaultConnection")
         {
         }
    
         public static ApplicationDbContext Create()
         {
             return new ApplicationDbContext();
         } 
      }
    

    【讨论】:

    • 我不认为你的最后陈述是正确的。如果您将 ApplicationDbContext 更改为从 DbContext 派生,则会丢失在 IdentityDbContext 中进行的所有覆盖,这些覆盖对于身份系统的正确运行至关重要。 IdentityDbContext 覆盖了 OnModelCreating,因此还有一个额外的问题:如果需要在 ApplicationDbContext 中覆盖 OnModelCreating,则需要在 IdentityDbContext 中复制覆盖。 github.com/aspnet/Identity/blob/dev/src/…
    • 您应该在上一段的上下文中查看最后一条语句:“默认情况下,Asp.Net Identity 会为您生成一个新数据库,并且 ApplicationDbContext 配置为使用此数据库。您可以存储您的任何其他数据库中的身份验证相关实体,您只需要确保所有相关表都在那里。您还可以扩展此数据库以包含您在应用程序中使用的其他表,以便您可以使用相同的上下文一切都结束了。”
    • 所以如果用户使用自定义表来存储与身份相关的实体,IdentityDbContext 几乎没用,所有的数据操作都可以通过常规 DbContext 完成
    【解决方案2】:

    我认为您想创建自己的自定义身份验证数据库以进行登录身份验证。您需要逐步按照给定的说明进行操作。 1)您需要创建自己的类来实现自定义身份验证。例如,我正在创建以下学生课程。您可以在 MVC 的 MODEL 部分创建此类。

    class student{
    public int rollno{get;set;}
    public string firstName{get;set;}
    public string lastName{get;set;}
    

    2) 现在您将使用 identityDbContext 为学生类创建自己的 dbcontext。你可以像这样在 App_Start 部分创建这个类。

    public class ApplicationDbContext : IdentityDbContext<student>
        {
            public ApplicationDbContext() : base()
            {
    
            }
    
            public static ApplicationDbContext Create()
            {
                return new ApplicationDbContext();
            }
    

    3) 现在您可以按如下方式在控制器中使用它

    public class HomeController : Controller
        {
            // GET: Home
            public async Task<ActionResult> Index()
            {
                var context = new ApplicationDbContext(); // DefaultConnection
                var store = new UserStore<student>(context);
                var manager = new UserManager<student>(store);
                var signInManager = new SignInManager<student, string>(manager,
                    HttpContext.GetOwinContext().Authentication);
                var username  = "Edward";
                var email = "abc@gmail.com";
                var password = "Your password";
                var user = await manager.FindByEmailAsync(email);
    
                if (user == null)
                {
                    user = new student                    {
                        UserName = username,//username ,Email are getting from identityDbContext and the other three RollNO,FirstName and LastName are your own Custom members.so like this you can extend your any kind of data you like add or extend with IdentityDbContext.
                        Email = email,
                        RollNo = "15",
                        FirstName = "David",
                        LastName = "Kandel"
                    };
    
                    await manager.CreateAsync(user, password);
                }
                else
                {
                    var result = await signInManager.PasswordSignInAsync(user.UserName, password, true, false);
    
                    if (result == SignInStatus.Success)
                    {
                        return Content("Hello, " +user.rollno + ""  + user.FirstName + " " + user.LastName);
                    }
    
                                    }
    
    
                return Content("Hello, Index");
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-21
      • 2020-09-19
      • 1970-01-01
      • 1970-01-01
      • 2019-12-23
      • 2021-08-03
      相关资源
      最近更新 更多