简体   繁体   中英

ASp.net Entity Framework multiple identity user entities

I'm currently refactoring multiple applications which access the same database for users. Each adds their own special properties to the user which results in a lot of null values... i do not like this. My idea was to use a own IdentityUser, dbContext and UserManager per Application. There is a base IdentityUser and the other ones derive from it. it looks like this:

The base user:

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

The dbContext and userManager for this user:

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

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

For the second user i did the following:

[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
}

The User2 table only has the two Properties for example. The Primary Key in User2 is the same as in the User Table and also a FK to it.

In an asp.net mvc Project i use only for example the User2 related classes. If i now start this application i get instantly the error message "Invalid Column name SpecialProperty1 and SpecialProperty2". Entity Frameworks seems to access the User Table which does not have this additional fields. It does not "merge" it with the User2 Table and return a User2 Entity. What can i do to achieve this or is there a different/better way on how to do it?

My main goal is to make this more clean and separate for this multiple applications while still all applications access the same database.

What you need to have is:

XYZ.Business.Enities.DLL (Class Library) - where you define your User classes:

class BaseUser
class User1 : BaseUser
class User2 : BaseUser
etc

XYZ.Infrastructure.DataRepository.DLL (Class Library) - your data repo, where you would have something like:

public IDbSet<BaseUser> Users

Based on that DLL you generate your database schema (Ef code-first). You will have a Users table with a Discriminator column (possible types: BaseUser, User1, User2, etc).

Your applications should reference the same common Entities assembly. In each application work with the specific user type.

eg

App1:

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

App2:

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

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

The point is... your different applications should reference the same Entities and Repository DLLs.

Maybe on top of your DataRepository you can build a generic user repo, which does the enforcement. Something along the lines of

public class UserRepository<T> where T : BaseUser
{
  public UserRepository(IDataRepository dataRepository)
  {
  }

  // ... expose underlying dataRepository.Users here, while enforcing the T
}

then you can have in your apps:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM