Beispiel #1
0
        /// <summary>
        /// 当用户添加后触发得方法。
        /// </summary>
        /// <param name="context">数据库事务操作实例。</param>
        /// <param name="user">用户实例。</param>
        /// <param name="cancellationToken">取消标志。</param>
        /// <returns>返回操作结果,返回<c>true</c>表示操作成功,将自动提交事务,如果<c>false</c>或发生错误,则回滚事务。</returns>
        public virtual async Task <bool> OnCreatedAsync(IDbTransactionContext <TUser> context, TUser user, CancellationToken cancellationToken = default)
        {
            //添加用户角色
            var roles = await context.As <TRole>().FetchAsync(x => x.IsDefault, cancellationToken);

            var urdb = context.As <TUserRole>();

            foreach (var role in roles)
            {
                var userRole = new TUserRole {
                    RoleId = role.Id, UserId = user.Id
                };
                await urdb.CreateAsync(userRole, cancellationToken);
            }
            //更新用户最大角色,用于显示等使用
            var maxRole = roles.OrderByDescending(x => x.RoleLevel).First();

            if (maxRole != null)
            {
                user.RoleId = maxRole.Id;
                await context.UpdateAsync(user.Id, new { user.RoleId }, cancellationToken);
            }
            //子账号
            if (user.ParentId > 0)
            {
                var sdb = context.As <UserIndex>();
                await sdb.CreateIndexAsync(user.Id, user.ParentId, cancellationToken);
            }

            return(true);
        }
        /// <summary>
        /// 更新父级Id实例事务时候新建索引。
        /// </summary>
        /// <typeparam name="TParentIndex">索引类型。</typeparam>
        /// <param name="db">数据库事务操作接口实例。</param>
        /// <param name="id">当前实例Id。</param>
        /// <param name="parentId">父级Id。</param>
        /// <param name="cancellationToken">取消标志。</param>
        /// <returns>返回添加结果。</returns>
        public static async Task <bool> UpdateIndexAsync <TParentIndex>(this IDbTransactionContext <TParentIndex> db, int id, int parentId, CancellationToken cancellationToken = default)
            where TParentIndex : IParentIndex, new()
        {
            await db.DeleteAsync(x => x.Id == id, cancellationToken);//删除原有的父级ID

            return(await db.CreateIndexAsync(id, parentId, cancellationToken));
        }
 /// <summary>
 /// Dispose unmanaged resources and/or set large fields 
 /// (managed/unmanaged) to null. This method will be called whether 
 /// the <see cref="Disposable.Dispose()"/> method is called by the 
 /// finalizer or your code.
 /// </summary>
 protected override void DisposeExtra()
 {
     _conn = null;
     _cmdList = null;
     _tContext = null;
     _entityConfigs = null;
 }
Beispiel #4
0
        /// <summary>
        /// 当用户添加后触发得方法。
        /// </summary>
        /// <param name="context">数据库事务操作实例。</param>
        /// <param name="user">用户实例。</param>
        /// <returns>返回操作结果,返回<c>true</c>表示操作成功,将自动提交事务,如果<c>false</c>或发生错误,则回滚事务。</returns>
        public virtual bool OnCreated(IDbTransactionContext <TUser> context, TUser user)
        {
            //添加用户角色
            var roles = context.As <TRole>().Fetch(x => x.IsDefault).ToList();
            var urdb  = context.As <TUserRole>();

            foreach (var role in roles)
            {
                var userRole = new TUserRole {
                    RoleId = role.Id, UserId = user.Id
                };
                urdb.Create(userRole);
            }
            //更新用户最大角色,用于显示等使用
            var maxRole = roles.OrderByDescending(x => x.RoleLevel).First();

            if (maxRole != null)
            {
                user.RoleId = maxRole.Id;
                context.Update(user.Id, new { user.RoleId });
            }
            //子账号
            if (user.ParentId > 0)
            {
                var sdb = context.As <UserIndex>();
                sdb.CreateIndex(user.Id, user.ParentId);
            }

            return(true);
        }
Beispiel #5
0
 public NoDisposableWrapperDbTransactionContext(IDbTransactionContext context)
 {
     if (context == null)
     {
         throw new ArgumentNullException("context");
     }
     this.context = context;
 }
 /// <summary>
 /// Dispose current transaction context associated with the storage context.
 /// </summary>
 public void DisposeTransactionContext()
 {
     if (TransactionExists)
     {
         _tContext.Dispose();
         _tContext = null;
     }
 }
Beispiel #7
0
        /// <summary>
        /// 当用户添加后触发得方法。
        /// </summary>
        /// <param name="context">数据库事务操作实例。</param>
        /// <param name="user">用户实例。</param>
        /// <param name="cancellationToken">取消标志。</param>
        /// <returns>返回操作结果,返回<c>true</c>表示操作成功,将自动提交事务,如果<c>false</c>或发生错误,则回滚事务。</returns>
        public virtual Task <bool> OnCreatedAsync(IDbTransactionContext <TUser> context, TUser user, CancellationToken cancellationToken = default)
        {
            //积分
            var usdb = context.As <UserScore>();

            return(usdb.CreateAsync(new UserScore {
                UserId = user.Id
            }, cancellationToken));
        }
Beispiel #8
0
        /// <summary>
        /// 当用户添加后触发得方法。
        /// </summary>
        /// <param name="context">数据库事务操作实例。</param>
        /// <param name="user">用户实例。</param>
        /// <returns>返回操作结果,返回<c>true</c>表示操作成功,将自动提交事务,如果<c>false</c>或发生错误,则回滚事务。</returns>
        public virtual bool OnCreated(IDbTransactionContext <TUser> context, TUser user)
        {
            //积分
            var usdb = context.As <UserScore>();

            return(usdb.Create(new UserScore {
                UserId = user.Id
            }));
        }
Beispiel #9
0
        public IDbTransactionContext Binded(bool readOnly = false)
        {
            if (currentDbTransactionContext != null)
            {
                throw new InvalidOperationException("No puede bindear dos IDbTransactionContext conteporaneamente.");
            }

            currentDbTransactionContext = new BindedDbTransactionContext(this, readOnly);
            return(currentDbTransactionContext);
        }
Beispiel #10
0
        /// <summary>
        /// 当用户添加后触发得方法。
        /// </summary>
        /// <param name="context">数据库事务操作实例。</param>
        /// <returns>返回操作结果,返回<c>true</c>表示操作成功,将自动提交事务,如果<c>false</c>或发生错误,则回滚事务。</returns>
        public bool OnCreated(IDbTransactionContext <User> context)
        {
            //添加用户角色
            var role = context.As <Role>()
                       .Find(x => x.NormalizedName == DefaultRole.Member.NormalizedName);
            var userRole = new UserRole {
                RoleId = role.RoleId, UserId = UserId
            };

            return(context.As <UserRole>().Create(userRole));
        }
Beispiel #11
0
        /// <summary>
        /// 设置用户最高级的角色。
        /// </summary>
        /// <param name="db">事务实例。</param>
        /// <param name="userId">用户Id。</param>
        /// <returns>返回设置结果。</returns>
        protected virtual bool SetMaxRole(IDbTransactionContext <TRole> db, int userId)
        {
            var role = db.AsQueryable()
                       .Select()
                       .OrderByDescending(x => x.RoleLevel)
                       .InnerJoin <TUserRole>((r, ur) => r.RoleId == ur.RoleId)
                       .Where <TUserRole>(x => x.UserId == userId)
                       .FirstOrDefault();

            return(db.As <TUser>().Update(x => x.UserId == userId, new { role.RoleId, RoleName = role.Name }));
        }
Beispiel #12
0
        /// <summary>
        /// 当角色更新前触发得方法。
        /// </summary>
        /// <param name="context">数据库事务操作实例。</param>
        /// <param name="cancellationToken">取消标志。</param>
        /// <returns>返回操作结果,返回<c>true</c>表示操作成功,将自动提交事务,如果<c>false</c>或发生错误,则回滚事务。</returns>
        public async Task <bool> OnUpdateAsync(IDbTransactionContext <Role> context, CancellationToken cancellationToken = default(CancellationToken))
        {
            //更改用户显示的角色名称
            var dbRole = await context.FindAsync(RoleId, cancellationToken);

            if (dbRole.Name != Name)
            {
                await context.As <User>().UpdateAsync(x => x.RoleId == RoleId, new { RoleName = Name }, cancellationToken);
            }
            return(true);
        }
Beispiel #13
0
        /// <summary>
        /// 当角色更新前触发得方法。
        /// </summary>
        /// <param name="context">数据库事务操作实例。</param>
        /// <returns>返回操作结果,返回<c>true</c>表示操作成功,将自动提交事务,如果<c>false</c>或发生错误,则回滚事务。</returns>
        public bool OnUpdate(IDbTransactionContext <Role> context)
        {
            //更改用户显示的角色名称
            var dbRole = context.Find(RoleId);

            if (dbRole.Name != Name)
            {
                context.As <User>().Update(x => x.RoleId == RoleId, new { RoleName = Name });
            }
            return(true);
        }
Beispiel #14
0
        /// <summary>
        /// 设置用户最高级的角色。
        /// </summary>
        /// <param name="db">事务实例。</param>
        /// <param name="userId">用户Id。</param>
        /// <param name="cancellationToken">取消标识。</param>
        /// <returns>返回设置结果。</returns>
        protected virtual async Task <bool> SetMaxRoleAsync(IDbTransactionContext <TRole> db, int userId, CancellationToken cancellationToken = default)
        {
            var role = await db.AsQueryable()
                       .Select()
                       .OrderByDescending(x => x.RoleLevel)
                       .InnerJoin <TUserRole>((r, ur) => r.RoleId == ur.RoleId)
                       .Where <TUserRole>(x => x.UserId == userId)
                       .FirstOrDefaultAsync(cancellationToken);

            return(await db.As <TUser>().UpdateAsync(x => x.UserId == userId, new { role.RoleId, RoleName = role.Name }, cancellationToken));
        }
        /// <summary>
        /// Get the current transaction context associated with the storage context. If no 
        /// transaction context is found, a new associated one is created and returned.
        /// </summary>
        public IDbTransactionContext GetDbTransactionContext()
        {
            ThrowIfDisposed();

            if (!TransactionExists)
            {
                _tContext = CreateDbTransactionContext();
            }

            return _tContext;
        }
        /// <summary>
        /// 添加实例事务时候新建索引。
        /// </summary>
        /// <typeparam name="TParentIndex">索引类型。</typeparam>
        /// <param name="db">数据库事务操作接口实例。</param>
        /// <param name="id">当前实例Id。</param>
        /// <param name="parentId">父级Id。</param>
        /// <param name="cancellationToken">取消标志。</param>
        /// <returns>返回添加结果。</returns>
        public static async Task <bool> CreateIndexAsync <TParentIndex>(this IDbTransactionContext <TParentIndex> db, int id, int parentId, CancellationToken cancellationToken = default)
            where TParentIndex : IParentIndex, new()
        {
            //最顶级无需更新
            if (parentId <= 0)
            {
                return(true);
            }
            await db.ExecuteNonQueryAsync($@"INSERT INTO {db.EntityType.Table}(ParentId, Id) SELECT ParentId, {id} FROM {db.EntityType.Table} WITH(NOLOCK) WHERE Id = {parentId};", cancellationToken : cancellationToken);

            return(await db.CreateAsync(new TParentIndex { Id = id, ParentId = parentId }, cancellationToken));
        }
Beispiel #17
0
        /// <summary>
        /// 当角色删除前触发得方法。
        /// </summary>
        /// <param name="context">数据库事务操作实例。</param>
        /// <returns>返回操作结果,返回<c>true</c>表示操作成功,将自动提交事务,如果<c>false</c>或发生错误,则回滚事务。</returns>
        public bool OnDelete(IDbTransactionContext <Role> context)
        {
            //更改用户显示的角色名称
            var basic  = context.Find(x => x.NormalizedName == DefaultRole.Member.NormalizedName);
            var dbRole = context.Find(RoleId);

            if (dbRole.Name != Name)
            {
                context.As <User>().Update(x => x.RoleId == basic.RoleId, new { basic.RoleId, RoleName = basic.Name });
            }
            return(true);
        }
Beispiel #18
0
        /// <summary>
        /// 当用户添加后触发得方法。
        /// </summary>
        /// <param name="context">数据库事务操作实例。</param>
        /// <param name="cancellationToken">取消标志。</param>
        /// <returns>返回操作结果,返回<c>true</c>表示操作成功,将自动提交事务,如果<c>false</c>或发生错误,则回滚事务。</returns>
        public async Task <bool> OnCreatedAsync(IDbTransactionContext <User> context, CancellationToken cancellationToken = default(CancellationToken))
        {
            //添加用户角色
            var role = await context.As <Role>()
                       .FindAsync(x => x.NormalizedName == DefaultRole.Member.NormalizedName, cancellationToken);

            var userRole = new UserRole {
                RoleId = role.RoleId, UserId = UserId
            };

            return(await context.As <UserRole>().CreateAsync(userRole, cancellationToken));
        }
Beispiel #19
0
        /// <summary>
        /// 进入一个事务上下文
        /// </summary>
        /// <param name="transaction"></param>
        /// <returns></returns>
        public static IDbTransactionContext EnterTransaction(IDbTransactionContext transaction)
        {
            if (transaction == null)
            {
                throw new ArgumentNullException(nameof(transaction));
            }


            transaction.RegisterDispose(new DbContext(currentHost.Value, transaction).Dispose);

            throw new NotImplementedException();
        }
Beispiel #20
0
 public void Bind(IDbTransactionContext currentContext)
 {
     if (currentContext == null)
     {
         throw new ArgumentNullException("currentContext");
     }
     if (currentDbTransactionContext != null)
     {
         throw new InvalidOperationException("No puede bindear dos IDbTransactionContext conteporaneamente.");
     }
     currentDbTransactionContext = currentContext;
 }
        /// <summary>
        /// Save all changes to a storage.
        /// </summary>
        /// <returns>Returns number of objects saved to the storage.</returns>
        public int SaveChanges()
        {
            ThrowIfDisposed();

            int retCount = 0;
            IDbTransactionContext privateTContext = null;

            Open();

            // MySQL does not support nested transaction as if this class is used with 
            // unit of work which wraps operation inside a transaction. So, checking for 
            // existing transaction before creating private transaction context.
            if (!TransactionExists)
            {
                privateTContext = CreateDbTransactionContext();
            }
            
            try
            {
                foreach (IDbCommandContext cmdContext in _cmdList)
                {
                    retCount += cmdContext.Execute();
                    cmdContext.Dispose();
                }

                if (privateTContext != null)
                {
                    privateTContext.Commit();
                }
            }
            catch (Exception)
            {
                if (privateTContext != null)
                {
                    privateTContext.Rollback();
                }

                throw;
            }
            finally
            {
                if (privateTContext != null)
                {
                    privateTContext.Dispose();
                }

                _cmdList.Clear();
                Close();
            }

            return retCount;
        }
 /// <summary>
 /// 添加实例事务时候新建索引。
 /// </summary>
 /// <typeparam name="TParentIndex">索引类型。</typeparam>
 /// <param name="db">数据库事务操作接口实例。</param>
 /// <param name="id">当前实例Id。</param>
 /// <param name="parentId">父级Id。</param>
 /// <returns>返回添加结果。</returns>
 public static bool CreateIndex <TParentIndex>(this IDbTransactionContext <TParentIndex> db, int id, int parentId)
     where TParentIndex : IParentIndex, new()
 {
     //最顶级无需更新
     if (parentId <= 0)
     {
         return(true);
     }
     db.ExecuteNonQuery($@"INSERT INTO {db.EntityType.Table}(ParentId, Id) SELECT ParentId, {id} FROM {db.EntityType.Table} WITH(NOLOCK) WHERE Id = {parentId};");
     return(db.Create(new TParentIndex {
         Id = id, ParentId = parentId
     }));
 }
Beispiel #23
0
        /// <summary>
        /// 进入一个事务上下文
        /// </summary>
        /// <param name="transaction">要进入的事务</param>
        /// <returns>事务上下文</returns>
        public static IDbTransactionContext EnterTransaction(IDbTransactionContext transaction)
        {
            if (transaction == null)
            {
                throw new ArgumentNullException(nameof(transaction));
            }


            transaction.RegisterDispose(DbContext.EnterContext(transaction));
            transaction.BeginTransaction();

            return(transaction);
        }
Beispiel #24
0
        /// <summary>
        /// 当角色删除前触发得方法。
        /// </summary>
        /// <param name="context">数据库事务操作实例。</param>
        /// <param name="cancellationToken">取消标志。</param>
        /// <returns>返回操作结果,返回<c>true</c>表示操作成功,将自动提交事务,如果<c>false</c>或发生错误,则回滚事务。</returns>
        public async Task <bool> OnDeleteAsync(IDbTransactionContext <Role> context, CancellationToken cancellationToken = default(CancellationToken))
        {
            //更改用户显示的角色名称
            var basic = await context.FindAsync(x => x.NormalizedName == DefaultRole.Member.NormalizedName, cancellationToken);

            var dbRole = await context.FindAsync(RoleId, cancellationToken);

            if (dbRole.Name != Name)
            {
                await context.As <User>().UpdateAsync(x => x.RoleId == basic.RoleId, new { basic.RoleId, RoleName = basic.Name }, cancellationToken);
            }
            return(true);
        }
Beispiel #25
0
        /// <summary>
        /// 添加用户。
        /// </summary>
        /// <param name="db">当前事务实例。</param>
        /// <param name="userName">用户名称。</param>
        /// <param name="password">密码。</param>
        /// <param name="roles">角色列表,不包含默认角色。</param>
        /// <param name="parentId">父级Id。</param>
        /// <returns>返回当前用户Id。</returns>
        protected async Task <int> CreateAsync(IDbTransactionContext <TUser> db, string userName, string password, List <TRole> roles, int parentId)
        {
            var user = new TUser();

            user.UserName           = userName;
            user.PasswordHash       = password;
            user.NickName           = user.UserName;
            user.NormalizedUserName = UserManager.NormalizeName(user.UserName);
            user.PasswordHash       = UserManager.HashPassword(user);
            user.ParentId           = parentId;

            if (!await db.CreateAsync(user))
            {
                Logger.LogCritical("添加用户实例失败:{0}", userName);
                return(0);
            }

            foreach (var handler in _handlers)
            {
                if (!await handler.OnCreatedAsync(db, user))
                {
                    Logger.LogCritical("触发用户事件失败:{0},类型:{1}", userName, handler.GetType().FullName);
                    return(0);
                }
            }

            var urdb = db.As <TUserRole>();

            foreach (var role in roles)
            {
                if (!await urdb.CreateAsync(new TUserRole {
                    RoleId = role.Id, UserId = user.Id
                }))
                {
                    Logger.LogCritical("添加用户角色失败:{0}({2}),角色:{1}({3})", userName, role.Name, user.Id, role.Id);
                    return(0);
                }
            }

            var maxRole = roles.OrderByDescending(x => x.RoleLevel).First();

            user.RoleId = maxRole.Id;
            if (await db.UpdateAsync(user.Id, new { user.RoleId }))
            {
                return(user.Id);
            }

            Logger.LogCritical("添加用户最高角色失败:{0},角色:{1}", userName, maxRole.Name);
            return(0);
        }
Beispiel #26
0
        /// <summary>
        /// 网站添加后调用的方法。
        /// </summary>
        /// <param name="context">当前事务管理器。</param>
        /// <param name="site">网站实例。</param>
        /// <returns>返回触发方法后的结果,如果返回<code>false</code>将回滚事件。</returns>
        public virtual async Task <bool> OnCreatedAsync(IDbTransactionContext <SiteAdapter> context, TSite site)
        {
            var sd = context.As <SiteDomain>();

            foreach (var domain in DefaultDomains)
            {
                if (!await sd.CreateAsync(new SiteDomain {
                    Domain = domain, SiteId = site.Id
                }))
                {
                    return(false);
                }
            }
            return(true);
        }
        /// <summary>
        /// 更新用户积分。
        /// </summary>
        /// <param name="db">数据库事务接口实例。</param>
        /// <param name="userId">用户Id。</param>
        /// <param name="score">用户积分。</param>
        /// <param name="remark">描述。</param>
        /// <param name="scoreType">积分使用类型。</param>
        /// <param name="cancellationToken">取消标志。</param>
        /// <returns>返回添加结果。</returns>
        public static async Task <UpdateScoreResult> UpdateScoreAsync(this IDbTransactionContext <UserScore> db, int userId, int score, string remark = null, ScoreType?scoreType = null, CancellationToken cancellationToken = default)
        {
            var userScore = await db.AsQueryable().WithNolock().Where(x => x.UserId == userId).FirstOrDefaultAsync(cancellationToken);

            if (userScore == null || userScore.Score < score)
            {
                return(UpdateScoreStatus.NotEnough);
            }

            var log = new ScoreLog();

            log.BeforeScore      = userScore.Score;
            log.Score            = -score;
            userScore.Score     -= score;
            userScore.ScoredDate = DateTimeOffset.Now;
            if (scoreType == null)
            {
                scoreType = score > 0 ? ScoreType.Consume : ScoreType.Recharge;
            }
            log.ScoreType = scoreType.Value;
            if (!await db.UpdateAsync(x => x.UserId == userId && x.RowVersion == userScore.RowVersion, new { userScore.Score, userScore.ScoredDate }, cancellationToken))
            {
                return(UpdateScoreStatus.ScoreError);
            }

            log.AfterScore = userScore.Score;
            log.Remark     = remark;
            log.UserId     = userId;

            var sdb = db.As <ScoreLog>();

            if (await sdb.CreateAsync(log, cancellationToken))
            {
                return(log.Id);
            }
            return(UpdateScoreStatus.LogError);
        }
Beispiel #28
0
 /// <summary>
 /// 创建模版表达式实例
 /// </summary>
 /// <param name="transaction">数据库事务对象</param>
 /// <param name="template">SQL 命令模版</param>
 /// <param name="parameters">模版参数列表</param>
 /// <returns>模版表达式</returns>
 public static DbExecutableQuery <ParameterizedQuery> T(this IDbTransactionContext <IDbExecutor <ParameterizedQuery> > transaction, string template, params object[] parameters)
 {
     return(transaction.DbExecutor.Template(template, parameters));
 }
Beispiel #29
0
 public AsyncDbTransactionContextWrapper(IDbTransactionContext context)
 {
     _context = context;
 }
Beispiel #30
0
 public void Unbind()
 {
     currentDbTransactionContext = null;
 }