Dapper在Oracle中QueryMultiple无效的解决方法.

Dapper在Oracle中QueryMultiple无效的解决方法.

  • 项目版本: .Net4.5.2, Dapper=>1.60.6, Oracle.ManagedDataAccess=>19.6.0,Oracle==>12C
  • 问题: 在Dapper中使用QueryMultiple,只能查询单SQL,如果是多条SQL,那么会提示SQL语句异常;
  • 分析:
    • Dapper对MSSQLSERVER支持最好,使用QueryMultiple没有任何问题;
    • Oracle和MSSQLSERVER对SQL的解析不同;

解决方法:

Dapper中有SqlMapper.IDynamicParameters,它是Dapper处理参数进行动态绑定的接口;

我们需要解决Oracle参数绑定的问题,

直接给出示例:

using Dapper;
using Oracle.ManagedDataAccess.Client;
using System.Collections.Generic;
using System.Data;

namespace LayIM.OracleServer
{
    public class OracleDynamicParameters : SqlMapper.IDynamicParameters
    {
        private readonly DynamicParameters dynamicParameters = new DynamicParameters();

        private readonly List oracleParameters = new List();

        public void Add(string name, OracleDbType oracleDbType, ParameterDirection direction, object value = null, int? size = null)
        {
            OracleParameter oracleParameter;
            if (size.HasValue)
            {
                oracleParameter = new OracleParameter(name, oracleDbType, size.Value, value, direction);
            }
            else
            {
                oracleParameter = new OracleParameter(name, oracleDbType, value, direction);
            }

            oracleParameters.Add(oracleParameter);
        }

        public void Add(string name, OracleDbType oracleDbType, ParameterDirection direction)
        {
            var oracleParameter = new OracleParameter(name, oracleDbType, direction);
            oracleParameters.Add(oracleParameter);
        }

        public void AddParameters(IDbCommand command, SqlMapper.Identity identity)
        {
            ((SqlMapper.IDynamicParameters)dynamicParameters).AddParameters(command, identity);

            var oracleCommand = command as OracleCommand;

            if (oracleCommand != null)
            {
                oracleCommand.Parameters.AddRange(oracleParameters.ToArray());
            }
        }
    }
}

然后给出QueryMultiple使用示例:

public override CommonResult GetInitInfo(long userId)
        {
            return _storage.UseConnection(connection =>
            {

                string sql = @"
BEGIN
OPEN :rslt1 FOR SELECT T.ID, T.USERNAME, T.SIGNIMAGE SIGN, NVL(T.AVATAR, '/AVATARS/user.jpg') AVATAR FROM S_USER T WHERE T.ID = :userId;
OPEN :rslt2 FOR SELECT T.ID, GROUP_NAME GROUPNAME FROM IM_FRIEND_GROUP T WHERE T.USER_ID = :userId;
OPEN :rslt3 FOR SELECT A.ID GID, C.ID, C.USERNAME, C.SIGNIMAGE SIGN, C.AVATAR FROM IM_FRIEND_GROUP A INNER JOIN IM_FRIEND_GROUP_DETAIL B ON A.ID = B.GROUP_ID LEFT JOIN S_USER C ON B.USER_ID = C.ID WHERE A.USER_ID = :userId;
OPEN :rslt4 FOR SELECT B.ID, B.NAME GROUPNAME, B.AVATAR FROM IM_BIG_GROUP_DETAIL A LEFT JOIN IM_BIG_GROUP B ON A.GROUP_ID = B.ID WHERE A.USER_ID = :userId;
END;
";
                OracleDynamicParameters dynParams = new OracleDynamicParameters();
                dynParams.Add(":rslt1", OracleDbType.RefCursor, ParameterDirection.Output);
                dynParams.Add(":rslt2", OracleDbType.RefCursor, ParameterDirection.Output);
                dynParams.Add(":rslt3", OracleDbType.RefCursor, ParameterDirection.Output);
                dynParams.Add(":rslt4", OracleDbType.RefCursor, ParameterDirection.Output);
                dynParams.Add(":userId", OracleDbType.Int32, ParameterDirection.Input, userId);

                SqlMapper.GridReader reader = connection.QueryMultiple(sql, param: dynParams);

                var result = new BaseListResult();
                result.mine = reader.ReadFirstOrDefault();
                //处理friend逻辑 start
                var friend = reader.Read();
                var groupUsers = reader.Read();

                friend.ToList().ForEach(f =>
                {
                    //每一组的人分配给各个组
                    f.list = groupUsers?.Where(x => x.gid == f.id);
                });
                result.friend = friend;
                //处理friend逻辑 end
                //读取用户所在群
                result.group = reader.Read();

                _storage.ReleaseConnection(connection);
                return new CommonResult { code = result.mine == null ? 1 : 0, msg = result.mine == null ? "用户不存在" : "", data = result };
            });
        }

给出结果截图:

Dapper在Oracle中QueryMultiple无效的解决方法._第1张图片

希望对大家有帮助.

你可能感兴趣的:(.net,LayIM)