【问题标题】:ASp.net Entity Framework multiple identity user entitiesASp.net Entity Framework 多身份用户实体
【发布时间】:2017-04-03 07:08:08
【问题描述】:

我目前正在重构为用户访问同一数据库的多个应用程序。每个人都向用户添加了自己的特殊属性,这会导致很多空值……我不喜欢这样。我的想法是为每个应用程序使用自己的 IdentityUser、dbContext 和 UserManager。 有一个基础 IdentityUser ,其他的从它派生。它看起来像这样:

基础用户:

 public class User : IdentityUser
 {
   public string Username {get;set;}
   public string Email {get;set;}
   ...
 }

该用户的 dbContext 和 userManager:

public class UserAuthenticationDbContext : IdentityDbContext<User>
{
  //code here
}

public class UserManager : UserManager<User>
{
 //code here
}

对于第二个用户,我做了以下操作:

[Table("User2")]
public class User2 : User
{
    public string SpecialProperty1 {get;set;}
    public string SpecialProperty2 {get;set;}
}

public class User2Manager : UserManager<User2>
{
  // code here
}

public class User2AuthenticationDbContext : IdentityDbContext<User2>
{
   //code here
}

例如,User2 表只有两个属性。 User2 中的主键与用户表中的主键相同,也是它的 FK。

在 asp.net mvc 项目中,我仅使用与 User2 相关的类。如果我现在启动此应用程序,我会立即收到错误消息“无效的列名 SpecialProperty1 和 SpecialProperty2”。 实体框架似乎可以访问没有此附加字段的用户表。它不会将其与 User2 表“合并”并返回 User2 实体。 我能做些什么来实现这一点,或者有没有不同/更好的方法来做到这一点?

我的主要目标是让这多个应用程序更加干净和独立,同时所有应用程序都访问同一个数据库。

【问题讨论】:

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


    【解决方案1】:

    你需要的是:

    XYZ.Business.Enities.DLL (Class Library) - 您在其中定义用户类:

    class BaseUser
    class User1 : BaseUser
    class User2 : BaseUser
    etc
    

    XYZ.Infrastructure.DataRepository.DLL (Class Library) - 你的数据仓库,你会在其中有类似的东西:

    public IDbSet<BaseUser> Users
    

    基于该 DLL,您可以生成数据库模式(Ef 代码优先)。您将拥有一个带有 Discriminator 列的用户表(可能的类型:BaseUser、User1、User2 等)。

    您的应用程序应该引用相同的通用Entities 程序集。在每个应用程序中使用特定的用户类型。

    例如

    应用1:

    User1 user = new User1();
    this.dataRepository.Users.Add(user);
    

    应用程序2:

    User2 user = new User2();
    this.dataRepository.Users.Add(user);
    

    App3: var users = this.dataRepository.Users.Where(user is User3)

    重点是...您的不同应用程序应该引用相同的实体和存储库 DLL。

    也许在您的DataRepository 之上,您可以构建一个通用的用户存储库,用于执行。类似于

    public class UserRepository<T> where T : BaseUser
    {
      public UserRepository(IDataRepository dataRepository)
      {
      }
    
      // ... expose underlying dataRepository.Users here, while enforcing the T
    }
    

    那么你可以在你的应用中拥有:

    var userRepo = new UserRepository<User1>(this.DataRepository);
    

    【讨论】:

    • 感谢您的回答。我把它放在一个自己的类库中,这样就可以从所有应用程序中访问它。在您的示例中,所有内容仍将位于一张表中,对吗?只是用包含类型名或其他内容的列分隔。有没有办法用 TablePerType 做到这一点?就像这里的例子:weblogs.asp.net/manavi/… 这是我试图做的,但我在 mvc 应用程序中收到错误消息......
    • 在我的示例中,所有用户都将位于同一个表中,EF 将根据鉴别器列自动确定该表中的记录。每个类的每个属性都有列。如果你不想重复,你应该有继承和公共基类。但是,您最终总会有一些 NULL 列(与某种类型的记录无关)——这不应该打扰您。
    • 为什么要考虑数据库?如果您采用 EF 代码优先方法,那么它不应该是困扰您的事情。
    • 可能你是对的。我太在意它了:)。我会用你的方法尝试一下,看看 mvc 应用程序中的错误现在是否消失了。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2017-05-05
    • 1970-01-01
    • 2011-11-09
    • 1970-01-01
    • 1970-01-01
    • 2018-05-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多