/// <summary> /// Выполнить reader.Read() и преобразовать считанную строку, /// после чего закрыть запрос; элемент item должен быть создан перед вызовом. /// </summary> /// <param name="reader">Открытый запрос</param> /// <param name="item">Целевой элемент</param> /// <param name="group">Наименое группы размеченных свойств, /// если null, то все свойства</param> /// <param name="pool">Пул разделяемых объектов</param> public static void ReadOnce(SqlDataReader reader, TItem item, string group = null, SpmSharedItemPool pool = null) { SpmReader <TItem> spm = new SpmReader <TItem>(reader, pool, group); spm.ReadOnce(item); }
public SpmReader(SqlDataReader reader, SpmSharedItemPool pool = null, string group = null) { if (reader == null) { throw new ArgumentNullException("reader"); } this.dataReader = reader; this.indices = new Dictionary <string, int>(this.DataReader.FieldCount); for (int i = 0; i < this.DataReader.FieldCount; i++) { string name = this.DataReader.GetName(i); if (indices.ContainsKey(name)) { throw new ArgumentException(String.Concat("Колонка с именем ", name, " встречается в запросе более одного раза")); } indices.Add(name, i); } this.itemReader = new SpmItem <TItem>(this, null, group); this.sharedPool = pool; }
public override System.Runtime.Remoting.Messaging.IMessage Invoke(System.Runtime.Remoting.Messaging.IMessage msg) { IMethodCallMessage methodCall = (IMethodCallMessage)msg; MethodInfo methodInfo = (MethodInfo)methodCall.MethodBase; ParameterInfo[] parameters = methodInfo.GetParameters(); SqlCommand command = getSqlCommand(methodInfo); bool hasOutput = false; SpmSharedItemPool itemPool = null; int itemPoolArgIndex = -1; for (int i = 0; i < parameters.Length; i++) { if (parameters[i].ParameterType.Equals(typeof(SpmSharedItemPool))) { if (itemPoolArgIndex < 0) { itemPoolArgIndex = i; itemPool = (SpmSharedItemPool)methodCall.Args[i]; } else { throw new ArgumentException("SpmItemPool в параметрах встречается более одного раза"); } } else { hasOutput |= command.Parameters.Add( getSqlParameter(parameters[i], methodCall.Args[i])).Direction != ParameterDirection.Input; } } object result = null; bool mustClosed = false; try { command.Connection = new SqlConnection(this.connectionString, this.credential); mustClosed = true; command.Connection.Open(); result = executeCommand(methodInfo, command, ref mustClosed, itemPool); } catch (Exception ex) { return(new ReturnMessage(ex, msg as IMethodCallMessage)); } finally { if (mustClosed) { command.Connection.Close(); } command.Dispose(); } object[] outArgs = null; if (hasOutput) { outArgs = new object[methodCall.ArgCount]; int currCount = itemPoolArgIndex < 0 ? outArgs.Length : itemPoolArgIndex; for (int i = 0; i < currCount; i++) { outArgs[i] = parameters[i].ParameterType.IsByRef ? command.Parameters[i].Value : null; } for (int i = ++currCount; i < outArgs.Length; i++) { outArgs[i] = parameters[i - 1].ParameterType.IsByRef ? command.Parameters[i - 1].Value : null; } } return(new ReturnMessage(result, outArgs, outArgs == null ? 0 : outArgs.Length, methodCall.LogicalCallContext, methodCall)); }
private object executeCommand(MethodInfo methodInfo, SqlCommand command, ref bool mustClosed, SpmSharedItemPool itemPool) { object result = null; Type retType = methodInfo.ReturnType; if (typeof(void).Equals(retType)) { // no result, execute non-query command.ExecuteNonQuery(); } else { if (typeof(SqlReturn).Equals(retType)) { // no result, execute non-query with return value SqlParameter retVal = command.Parameters.Add( new SqlParameter("@RETURN_VALUE", SqlDbType.Int) { Direction = ParameterDirection.ReturnValue }); command.ExecuteNonQuery(); result = new SqlReturn(retVal.Value is int?(int)retVal.Value: 0); } else { if (typeof(SqlDataReader).Equals(retType)) { result = command.ExecuteReader(CommandBehavior.CloseConnection); mustClosed = false; } else { if (typeof(DataTable).Equals(retType)) { using (SqlDataAdapter da = new SqlDataAdapter(command)) { DataSet ds = new DataSet(); da.Fill(ds); if (ds.Tables.Count > 0) { result = ds.Tables[0]; ds.Tables.RemoveAt(0); } } } else { if (typeof(DataSet).Equals(retType)) { using (SqlDataAdapter da = new SqlDataAdapter(command)) { DataSet ds = new DataSet(); da.Fill(ds); result = ds; } } else { if (retType.IsGenericType && retType.GetGenericTypeDefinition().Equals(typeof(IEnumerable <>))) { ReadEnumDelegate readEnum = GetReadEnum(retType.GetGenericArguments()[0]); result = readEnum(command.ExecuteReader(CommandBehavior.CloseConnection), itemPool); mustClosed = false; } else { result = command.ExecuteScalar(); //throw new ArgumentException(String.Concat("Unsupported return type: ", // methodInfo.ReturnType.ToString())); } } } } } } return(result); }
/// <summary> /// Получить все элементы в виде последовательности и закрыть запрос /// </summary> /// <param name="reader">Открытый запрос</param> /// <param name="pool">Пул разделяемых объектов</param> /// <returns>Последовательность</returns> public static IEnumerable <TItem> Read(SqlDataReader reader, SpmSharedItemPool pool = null) { SpmReader <TItem> spm = new SpmReader <TItem>(reader, pool); return(spm.Read()); }