예제 #1
0
        protected override DbCommand BuidUpdateCommand(SqlUpdateCommand updateCommand)
        {
            NpgsqlCommand     cmd = new NpgsqlCommand();
            BuildQueryContext ctx = new BuildQueryContext(cmd, updateCommand);

            //设置上下文
            ctx.BeginBuildQuery(updateCommand);

            EntityModel model = Runtime.RuntimeContext.Current.GetModelAsync <EntityModel>(updateCommand.T.ModelID).Result;

            ctx.AppendFormat("Update \"{0}\" t Set ", model.GetSqlTableName(false, null));
            ctx.CurrentQueryInfo.BuildStep = BuildQueryStep.BuildUpdateSet;
            for (int i = 0; i < updateCommand.UpdateItems.Count; i++)
            {
                BuildExpression(updateCommand.UpdateItems[i], ctx);
                if (i < updateCommand.UpdateItems.Count - 1)
                {
                    ctx.Append(",");
                }
            }

            //构建Where
            ctx.CurrentQueryInfo.BuildStep = BuildQueryStep.BuildWhere;
            if (!Expression.IsNull(updateCommand.Filter))
            {
                ctx.Append(" Where ");
                BuildExpression(ctx.CurrentQuery.Filter, ctx);
            }

            //构建Join
            ctx.CurrentQueryInfo.BuildStep = BuildQueryStep.BuildJoin;
            SqlQueryBase q1 = (SqlQueryBase)ctx.CurrentQuery;

            if (q1.HasJoins) //先处理每个手工的联接及每个手工联接相应的自动联接
            {
                BuildJoins(q1.Joins, ctx);
            }
            ctx.BuildQueryAutoJoins(q1); //再处理自动联接

            //最后处理返回值
            if (updateCommand.OutputItems != null)
            {
                ctx.CurrentQueryInfo.BuildStep = BuildQueryStep.BuildWhere; //TODO: fix this?
                ctx.Append(" RETURNING ");
                for (int i = 0; i < updateCommand.OutputItems.Length; i++)
                {
                    var field = (FieldExpression)updateCommand.OutputItems[i];
                    ctx.AppendFormat("\"{0}\"", field.Name);
                    if (i != updateCommand.OutputItems.Length - 1)
                    {
                        ctx.Append(",");
                    }
                }
            }

            //结束用于附加条件,注意:仅在Upsert时这样操作
            ctx.EndBuildQuery(updateCommand);
            return(cmd);
        }
예제 #2
0
        public async Task ExecCommandAsync(SqlUpdateCommand updateCommand, DbTransaction txn = null)
        {
            //暂不支持无条件更新,以防止误操作
            if (Expressions.Expression.IsNull(updateCommand.Filter))
            {
                throw new NotSupportedException("Update must assign Where condition");
            }

            var cmd = BuidUpdateCommand(updateCommand);

            cmd.Connection  = txn != null ? txn.Connection : MakeConnection();
            cmd.Transaction = txn;
            if (txn == null)
            {
                await cmd.Connection.OpenAsync();
            }
            Log.Debug(cmd.CommandText);
            //执行命令
            if (updateCommand.OutputItems != null && UseReaderForOutput) //返回字段通过DbReader读取
            {
                try
                {
                    using var reader = await cmd.ExecuteReaderAsync();

                    while (await reader.ReadAsync())
                    {
                        updateCommand.SetOutputs(new SqlRowReader(reader));
                    }
                }
                catch (Exception ex)
                {
                    Log.Warn($"Exec sql error: {ex.Message}\n{cmd.CommandText}");
                    throw;
                }
                finally
                {
                    if (txn == null)
                    {
                        cmd.Connection.Dispose();
                    }
                }
            }
            else
            {
                try
                {
                    await cmd.ExecuteNonQueryAsync();
                }
                catch (Exception ex)
                {
                    Log.Warn($"Exec sql error: {ex.Message}\n{cmd.CommandText}");
                    throw;
                }
                finally
                {
                    if (txn == null)
                    {
                        cmd.Connection.Dispose();
                    }
                }

                if (updateCommand.OutputItems != null)
                {
                    throw new NotImplementedException(); //TODO:读取输出参数值
                }
            }
        }