It should be possible to use the identity system with POCO and Database First, but you'll have to make a couple of tweaks:

  1. Update the .tt-file for POCO generation to make the entity classes partial. That will make it possible for you to supply additional implementation in a separate file.
  2. Make a partial implementation of the User class in another file

 

partial User : IUser
{
}

That will make the User class implement the right interface, without touching the actual generated files (editing generated files is always a bad idea).


My steps are very similar but I wanted to share.

1) Create a new MVC5 project

2) Create a new Model.edmx. Even if it's a new database and has no tables.

3) Edit web.config and replace this generated connectionstring:

<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-SSFInventory-20140521115734.mdf;Initial Catalog=aspnet-SSFInventory-20140521115734;Integrated Security=True" providerName="System.Data.SqlClient" />

with this connectionstring:

<add name="DefaultConnection" connectionString="Data Source=.\SQLExpress;database=SSFInventory;integrated security=true;" providerName="System.Data.SqlClient" />

Afterwards, build and run the application. Register a user and then the tables will be created.


EDIT: ASP.NET Identity with EF Database First for MVC5 CodePlex Project Template.


I wanted to use an existing database and create relationships with ApplicationUser. This is how I did it using SQL Server but the same idea would probably work with any DB.

  1. Create an MVC Project
  2. Open the DB listed under the DefaultConnection in Web.config. It will be called (aspnet-[timestamp] or something like that.)
  3. Script the database tables.
  4. Insert the scripted tables into existing database in SQL Server Management Studio.
  5. Customize and add relationships to ApplicationUser (if necessary).
  6. Create new Web Project > MVC > DB First Project > Import DB with EF ... Excluding the Identity Classes you inserted.
  7. In IdentityModels.cs change the ApplicationDbContext :base("DefaltConnection") to use your project's DbContext.

Edit: Asp.Net Identity Class Diagram enter image description here


IdentityUser is worthless here because it's the code-first object used by the UserStore for authentication. After defining my own User object, I implemented a partial class that implements IUser which is used by the UserManager class. I wanted my Ids to be int instead of string so I just return the UserID's toString(). Similarly I wanted n in Username to be uncapitalized.

public partial class User : IUser
{

    public string Id
    {
        get { return this.UserID.ToString(); }
    }

    public string UserName
    {
        get
        {
            return this.Username;
        }
        set
        {
            this.Username = value;
        }
    }
}

You by no means need IUser. It's only an interface used by the UserManager. So if you want to define a different "IUser" you would have to rewrite this class to use your own implementation.

public class UserManager<TUser> : IDisposable where TUser: IUser

You now write your own UserStore which handles all of the storage of users, claims, roles, etc. Implement the interfaces of everything that the code-first UserStore does and change where TUser : IdentityUser to where TUser : User where "User" is your entity object

public class MyUserStore<TUser> : IUserLoginStore<TUser>, IUserClaimStore<TUser>, IUserRoleStore<TUser>, IUserPasswordStore<TUser>, IUserSecurityStampStore<TUser>, IUserStore<TUser>, IDisposable where TUser : User
{
    private readonly MyAppEntities _context;
    public MyUserStore(MyAppEntities dbContext)
    { 
        _context = dbContext; 
    }

    //Interface definitions
}

Here are a couple examples on some of the interface implementations

async Task IUserStore<TUser>.CreateAsync(TUser user)
{
    user.CreatedDate = DateTime.Now;
    _context.Users.Add(user);
    await _context.SaveChangesAsync();
}

async Task IUserStore<TUser>.DeleteAsync(TUser user)
{
    _context.Users.Remove(user);
    await _context.SaveChangesAsync();
}

Using the MVC 5 template, I changed the AccountController to look like this.

public AccountController()
        : this(new UserManager<User>(new MyUserStore<User>(new MyAppEntities())))
{
}

Now logging in should work with your own tables.