internal MyCatParameterCollection AlignParamsWithDb(MyCatParameterCollection parameterCollection) { var alignedParams = new MyCatParameterCollection(); var returnParam = parameterCollection.FirstOrDefault(x => x.Direction == ParameterDirection.ReturnValue); foreach (var cachedParam in m_parameters) { MyCatParameter alignParam; if (cachedParam.Direction == ParameterDirection.ReturnValue) { if (returnParam == null) { throw new InvalidOperationException($"Attempt to call stored function {FullyQualified} without specifying a return parameter"); } alignParam = returnParam; } else { var index = parameterCollection.NormalizedIndexOf(cachedParam.Name); if (index == -1) { throw new ArgumentException($"Parameter '{cachedParam.Name}' not found in the collection."); } alignParam = parameterCollection[index]; } if (alignParam.Direction == default(ParameterDirection)) { alignParam.Direction = cachedParam.Direction; } if (alignParam.DbType == default(DbType)) { alignParam.DbType = cachedParam.DbType; } // cached parameters are oredered by ordinal position alignedParams.Add(alignParam); } return(alignedParams); }
public override async Task <DbDataReader> ExecuteReaderAsync(string commandText, MyCatParameterCollection parameterCollection, CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancellationToken) { var cachedProcedure = await m_command.Connection.GetCachedProcedure(ioBehavior, commandText, cancellationToken).ConfigureAwait(false); if (cachedProcedure != null) { parameterCollection = cachedProcedure.AlignParamsWithDb(parameterCollection); } MyCatParameter returnParam = null; m_outParams = new MyCatParameterCollection(); m_outParamNames = new List <string>(); var inParams = new MyCatParameterCollection(); var argParamNames = new List <string>(); var inOutSetParams = ""; for (var i = 0; i < parameterCollection.Count; i++) { var param = parameterCollection[i]; var inName = "@inParam" + i; var outName = "@outParam" + i; switch (param.Direction) { case 0: case ParameterDirection.Input: case ParameterDirection.InputOutput: var inParam = param.WithParameterName(inName); inParams.Add(inParam); if (param.Direction == ParameterDirection.InputOutput) { inOutSetParams += $"SET {outName}={inName}; "; goto case ParameterDirection.Output; } argParamNames.Add(inName); break; case ParameterDirection.Output: m_outParams.Add(param); m_outParamNames.Add(outName); argParamNames.Add(outName); break; case ParameterDirection.ReturnValue: returnParam = param; break; } } // if a return param is set, assume it is a funciton. otherwise, assume stored procedure commandText += "(" + string.Join(", ", argParamNames) + ")"; if (returnParam == null) { commandText = inOutSetParams + "CALL " + commandText; if (m_outParams.Count > 0) { m_setParamsFlags = true; m_cancellationToken = cancellationToken; } } else { commandText = "SELECT " + commandText; } var reader = (MyCatDataReader)await base.ExecuteReaderAsync(commandText, inParams, behavior, ioBehavior, cancellationToken).ConfigureAwait(false); if (returnParam != null && await reader.ReadAsync(ioBehavior, cancellationToken).ConfigureAwait(false)) { returnParam.Value = reader.GetValue(0); } return(reader); }