ASp.net Entity Framework 多个身份用户实体
ASp.net Entity Framework multiple identity user entities
我目前正在重构为用户访问同一个数据库的多个应用程序。每个人都向用户添加了自己的特殊属性,这会导致很多空值……我不喜欢这样。我的想法是为每个应用程序使用自己的 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 table 例如只有两个属性。 User2 中的主键与用户 Table 中的主键相同,也是它的外键。
在一个 asp.net mvc 项目中,我仅使用与 User2 相关的示例 类。如果我现在启动这个应用程序,我会立即收到错误消息 "Invalid Column name SpecialProperty1 and SpecialProperty2"。
实体框架似乎访问了没有此附加字段的用户 Table。它不 "merge" 它与 User2 Table 和 return 一个 User2 实体。
我该怎么做才能实现这一目标,或者是否有 different/better 方法来实现这一目标?
我的主要目标是让这多个应用程序更加干净和独立,同时所有应用程序仍然访问同一个数据库。
您需要具备的是:
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
列的用户 table(可能的类型:BaseUser、User1、User2 等)。
您的应用程序应引用相同的通用 Entities
程序集。在每个应用程序中使用特定的用户类型。
例如
App1:
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);
我目前正在重构为用户访问同一个数据库的多个应用程序。每个人都向用户添加了自己的特殊属性,这会导致很多空值……我不喜欢这样。我的想法是为每个应用程序使用自己的 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 table 例如只有两个属性。 User2 中的主键与用户 Table 中的主键相同,也是它的外键。
在一个 asp.net mvc 项目中,我仅使用与 User2 相关的示例 类。如果我现在启动这个应用程序,我会立即收到错误消息 "Invalid Column name SpecialProperty1 and SpecialProperty2"。 实体框架似乎访问了没有此附加字段的用户 Table。它不 "merge" 它与 User2 Table 和 return 一个 User2 实体。 我该怎么做才能实现这一目标,或者是否有 different/better 方法来实现这一目标?
我的主要目标是让这多个应用程序更加干净和独立,同时所有应用程序仍然访问同一个数据库。
您需要具备的是:
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
列的用户 table(可能的类型:BaseUser、User1、User2 等)。
您的应用程序应引用相同的通用 Entities
程序集。在每个应用程序中使用特定的用户类型。
例如
App1:
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);