public async Task <bool> GetTwoFactorEnabledAsync(IdentityUser user)
        {
            using (SqlConnection conn = new SqlConnection(ConnectionString))
            {
                var db = IdentityDatabase.Init(conn, 2);

                return((await db.Users.GetAsync(user.Id)).TwoFactorEnabled);
            }
        }
        public async Task DeleteAsync(IdentityUser user)
        {
            using (SqlConnection conn = new SqlConnection(ConnectionString))
            {
                var db = IdentityDatabase.Init(conn, 2);

                await db.Users.DeleteAsync(user.Id);
            }
        }
        public async Task <bool> GetPhoneNumberConfirmedAsync(IdentityUser user)
        {
            using (SqlConnection conn = new SqlConnection(ConnectionString))
            {
                var db = IdentityDatabase.Init(conn, 2);

                return((await db.Users.GetAsync(user.Id)).PhoneNumberConfirmed);
            }
        }
        public async Task <string> GetEmailAsync(IdentityUser user)
        {
            using (SqlConnection conn = new SqlConnection(ConnectionString))
            {
                var db = IdentityDatabase.Init(conn, 2);

                return((await db.Users.GetAsync(user.Id)).Email);
            }
        }
        public async Task <bool> HasPasswordAsync(IdentityUser user)
        {
            using (SqlConnection conn = new SqlConnection(ConnectionString))
            {
                var db = IdentityDatabase.Init(conn, 2);

                IdentityUser u = await db.Users.GetAsync(user.Id);

                return(!string.IsNullOrEmpty(u.PasswordHash));
            }
        }
        public async Task CreateAsync(IdentityUser user)
        {
            using (SqlConnection conn = new SqlConnection(ConnectionString))
            {
                var db = IdentityDatabase.Init(conn, 2);

                var result = await FindByEmailAsync(user.Email);

                if (result == null)
                {
                    await db.Users.InsertAsync(user, removeId : false);
                }
            }
        }
        public async Task AddLoginAsync(IdentityUser user, UserLoginInfo login)
        {
            using (SqlConnection conn = new SqlConnection(ConnectionString))
            {
                var db = IdentityDatabase.Init(conn, 2);

                var instance = new IdentityUserLogin
                {
                    UserId        = user.Id,
                    LoginProvider = login.LoginProvider,
                    ProviderKey   = login.ProviderKey,
                };

                await db.UserLogins.InsertAsync(instance);
            }
        }
        public async Task SetTwoFactorEnabledAsync(IdentityUser user, bool enabled)
        {
            using (SqlConnection conn = new SqlConnection(ConnectionString))
            {
                var db = IdentityDatabase.Init(conn, 2);

                IdentityUser u = await db.Users.GetAsync(user.Id);

                if (u != null)
                {
                    u.TwoFactorEnabled = enabled;

                    await db.Users.UpdateAsync(u.Id, u);
                }
            }
        }
        public async Task SetPhoneNumberConfirmedAsync(IdentityUser user, bool confirmed)
        {
            using (SqlConnection conn = new SqlConnection(ConnectionString))
            {
                var db = IdentityDatabase.Init(conn, 2);

                IdentityUser u = await db.Users.GetAsync(user.Id);

                if (u != null)
                {
                    u.PhoneNumberConfirmed = confirmed;

                    await db.Users.UpdateAsync(u.Id, u);
                }
            }
        }
        public async Task SetEmailAsync(IdentityUser user, string email)
        {
            using (SqlConnection conn = new SqlConnection(ConnectionString))
            {
                var db = IdentityDatabase.Init(conn, 2);

                IdentityUser u = await db.Users.GetAsync(user.Id);

                if (u != null)
                {
                    u.Email = email;

                    await db.Users.UpdateAsync(u.Id, u);
                }
            }
        }
        public async Task SetPasswordHashAsync(IdentityUser user, string passwordHash)
        {
            using (SqlConnection conn = new SqlConnection(ConnectionString))
            {
                var db = IdentityDatabase.Init(conn, 2);

                IdentityUser u = await db.Users.GetAsync(user.Id);

                if (u != null)
                {
                    u.PasswordHash = passwordHash;

                    await db.Users.UpdateAsync(u.Id, u);
                }
            }
        }
        public async Task AddClaimAsync(IdentityUser user, Claim claim)
        {
            using (SqlConnection conn = new SqlConnection(ConnectionString))
            {
                var db = IdentityDatabase.Init(conn, 2);

                var instance = new IdentityUserClaim
                {
                    UserId     = user.Id,
                    ClaimType  = claim.Type,
                    ClaimValue = claim.Value,
                };

                await db.UserClaims.InsertAsync(instance);
            }
        }
        public async Task SetSecurityStampAsync(IdentityUser user, string stamp)
        {
            using (SqlConnection conn = new SqlConnection(ConnectionString))
            {
                var db = IdentityDatabase.Init(conn, 2);

                IdentityUser u = await db.Users.GetAsync(user.Id);

                if (u == null)
                {
                    throw new InvalidOperationException("Cannot find a user to set the security stamp.");
                }

                u.SecurityStamp = stamp;

                await db.Users.UpdateAsync(u.Id, u);
            }
        }
        public async Task AddToRoleAsync(IdentityUser user, string roleName)
        {
            using (SqlConnection conn = new SqlConnection(ConnectionString))
            {
                var db = IdentityDatabase.Init(conn, 2);

                IdentityRole role = (await conn.QueryAsync <IdentityRole>(@"select * from Roles where Name=@RoleName", new { RoleName = roleName })).SingleOrDefault();
                if (role == null)
                {
                    throw new InvalidOperationException(string.Format("Role {0} not found.", roleName));
                }

                var instance = new IdentityUserRole
                {
                    RoleId = role.Id,
                    UserId = user.Id,
                };

                await db.UserRoles.InsertAsync(instance);
            }
        }
        private async Task SetUserField(IdentityUser user, string fieldName, object value)
        {
            var pi = user.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public).SingleOrDefault(x => x.Name == fieldName);

            if (pi == null)
            {
                throw new ArgumentException(string.Format("Property name {0} does not exist for type IdentityUser.", fieldName));
            }

            using (SqlConnection conn = new SqlConnection(ConnectionString))
            {
                var db = IdentityDatabase.Init(conn, 2);

                IdentityUser u = await db.Users.GetAsync(user.Id);

                if (u != null)
                {
                    pi.SetValue(u, value);

                    await db.Users.UpdateAsync(u.Id, u);
                }
            }
        }
        public async Task <int> IncrementAccessFailedCountAsync(IdentityUser user)
        {
            //int result;

            using (SqlConnection conn = new SqlConnection(ConnectionString))
            {
                var db = IdentityDatabase.Init(conn, 2);

                IdentityUser u = await db.Users.GetAsync(user.Id);

                if (u == null)
                {
                    throw new ArgumentException("Cannot find user.");
                }

                int result = u.AccessFailedCount++;

                await db.Users.UpdateAsync(u.Id, u);

                return(result);
            }

            //return result;
        }