MVC5 Identity + EntityFramework 中的多个上下文

Posted

技术标签:

【中文标题】MVC5 Identity + EntityFramework 中的多个上下文【英文标题】:MVC5 Identity + multiple context in EntityFramework 【发布时间】:2015-01-04 15:10:39 【问题描述】:

我有一个使用默认身份验证的 MVC 5 应用程序。 用户配置文件是我们模型的一部分,这意味着有几个类具有 UserInfo 的外键。 有 2 个 DbContext,一个用于模型,另一个用于 UserInfo。

 public class ApplicationDbContext : IdentityDbContext<UserInfo>
    
        public ApplicationDbContext()
            : base("Profile")
        
        

    



 public class UserInfo : IdentityUser
        
            public UserInfo ()
            
                LibraryItems = new List<LibraryItem>();
                if (UserGroup == UserGroupEnum.ANALYST)
                
                    Companies = new List<Company>();
                
                DateCreate = DateTime.Now;
                DateUpdate = DateTime.Now;
                DateDelete = DateTime.Now;
            

            [DisplayColumnInIndex]
            [DisplayName("Is Active ?")]
            public bool IsActive  get; set; 

            [Timestamp]
            public byte[] RowVersion  get; set; 

            //[ValidateFile(ErrorMessage = "Please select a PNG image smaller than 1MB")]
            //[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "0:MM/dd/yyyy")]
            [Editable(false, AllowInitialValue = true)]
            public DateTime DateCreate  get; set; 

            //[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "0:MM/dd/yyyy")]
            public DateTime DateUpdate  get; set; 

            //[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "0:MM/dd/yyyy")]
            public DateTime DateDelete  get; set; 

            [DisplayColumnInIndex]
            public String Name  get; set; 
            [DisplayColumnInIndex]
            public String FirstName  get; set; 

            [DisplayColumnInIndex]
            public String Pseudo  get; set; 

            [DisplayColumnInIndex]
            public string PhoneNumber  get; set; 

            [DisplayColumnInIndex]
            public String Company  get; set; 

            [DisplayName("Name_Id")]
            [ForeignKey("FullName")]
            public int? NameId  get; set; 
            [DisplayColumnInIndex]
            public UserGroupEnum UserGroup  get; set; 

            [DisplayColumnInIndex]
            public UserStatusEnum UserStatus  get; set; 

            public virtual Name FullName  get; set; 
    


public class Comment

       // more properties
        [DisplayName("UserInfoId")]
        [ForeignKey("UserInfo")]
        public virtual String UserInfoId  get; set; 


public class Like

      // more properties
        [DisplayName("UserInfoId")]
        [ForeignKey("UserInfo")]
        public virtual String UserInfoId  get; set; 

我的 userInfo 还具有第二个 DBontext 的其他表的外键。

设计我们的身份验证系统的最佳方式是什么?并保持两个上下文之间的关系。

提前致谢。

【问题讨论】:

【参考方案1】:

我最近提出的解决方案是为 ASP.NET 身份数据和您的业务实体使用单一上下文:

public class DatabaseContext : IdentityDbContext<UserInfo>

    public virtual DbSet<Comment> Comments  get; set;  // Your business entities

    public DatabaseContext()
        : base("name=DatabaseContext")
    
    

请注意,DatabaseContext 继承自 IdentityDbContext&lt;UserInfo&gt;

这种方法有一些取舍:例如,您的数据访问层应该引用Microsoft.AspNet.Identity.CoreMicrosoft.AspNet.Identity.EntityFramework;但是,如果您使用依赖注入或实体框架迁移,则在您的项目中拥有单个数据库上下文会使事情变得更容易。

【讨论】:

确实如此。如果您要在您的身份用户实体和任何其他实体之间建立任何关系,它们必须都在相同的上下文中。否则,您必须执行多个查询,例如从一个上下文中获取用户,然后使用外键属性中的值在另一个上下文中查找相关对象。这是可行的,但不是最有效的处理方式。 嗯,不,但出于不同的原因。如果您的用户实体上有任何导航属性到您想要在单独的上下文中的其他类型,哎呀,它们实际上是您的用户类所在的上下文的一部分。因为 EF 无法管理关系,除非它拥有所有涉及的实体,它基本上为没有自己的DbSet 的任何引用实体创建隐式DbSets。这意味着该上下文的迁移为这些相关实体创建表,并且它们不能同时由另一个上下文管理。 没有导航属性,你就没有延迟加载,所以你真正需要处理的只是一些值类型的“外键”属性。

以上是关于MVC5 Identity + EntityFramework 中的多个上下文的主要内容,如果未能解决你的问题,请参考以下文章

在 Asp.Net mvc5 Identity 1.0.0 版中忘记密码

为啥 ASP.Net Identity 不支持删除

如何获得当前用户,以及如何使用User类的MVC5

MVC5 - ASP.NET Identity登录原理 - Claims-based认证和OWIN

MVC 5 以同步方式使用 Identity 2 创建用户

如何与 Windows 服务应用程序共享 MVC 5 Identity 2.0 身份验证(尤其是 SignInManager)?