Search code examples
c#sql.netasp.net-coreunit-of-work

Unit of Work with Identity on ASP.NET Core


I'm creating web api for a mobile application, I need when user registering add the data to database, I want to add the data to multiple tables

My User table design :

  • AspnetUsers : Default identity table
  • StudentUsers: The second table of user detail
  • TeacherUsers: Third table for user

When on registering, user selecting which they're student or teacher. The problem here is, there is two table when registering, I want to use Unit of Work for that situation, to prevent data saving fails. If data fails not to add the data to other table.

But how can I implement this into identity?


Solution

  • You do not need to overthink/overdo Unit Of Work with Entity Framework Core.

    See:

    https://gunnarpeipman.com/ef-core-repository-unit-of-work/

    So to get your "transaction", you will call

    myInjectedContext.BeginTransaction().
    /* alter any/all of the 3 DbSets */
        myInjectedContext.Commit();
    

    where myInjectedContext is a IDataContext.

    public class MyTransactionallyFriendlyDbContext : DbContext /*(, IDataContext) */
    {
        public LasteDbContext(DbContextOptions<LasteDbContext> options)
            : base(options)
        {
        }
     
        public DbSet<AspnetUser> AspnetUsers { get; set; }
        public DbSet<StudentUser> StudentUsers { get; set; }
        public DbSet<TeacherUser> TeacherUsers { get; set; }
        
        private IDbContextTransaction _transaction;
     
        public void BeginTransaction()
        { 
            _transaction = Database.BeginTransaction();
        }
     
        public void Commit()
        {
            try
            {
                SaveChanges();
                _transaction.Commit();
            }
            finally
            {
                _transaction.Dispose();
            }        
        }
     
        public void Rollback()
        { 
            _transaction.Rollback();
            _transaction.Dispose();
        }
    }
    

    Here is an interface to satisfy Ioc/Unit Testing needs.

    public interface IDataContext
    {
        DbSet<AspnetUser> AspnetUsers { get; set; }
        DbSet<StudentUser> StudentUsers { get; set; }
        DbSet<TeacherUser> TeacherUsers { get; set; }
     
        void BeginTransaction();
        void Commit();
        void Rollback();
    }