/// <summary> /// Gets a array of constructor arguments to build an object with /// </summary> /// <param name="dstore">The datastore.</param> /// <param name="parminfo">The parms for the constructor.</param> /// <param name="ti">The type info</param> /// <param name="row">The row in the result set to use</param> /// <param name="dt">The query result set</param> /// <returns></returns> public static object[] SetConstructorArguments(this IDataManager dstore, ParameterInfo[] parminfo, TypeInfo ti, int row, QueryData dt) { object[] toReturn = new object[parminfo.Length]; for (int i = 0; i < parminfo.Length; i++) { ParameterInfo curr = parminfo[i]; //most system classes are handled just nicely by the type converter, only interested in user defined classes if (dt.FieldHasMapping(ti.DataFields[i].FieldName) && curr.ParameterType.IsSystemType()) toReturn[i] = dstore.Connection.TypeConverter.ConvertToType(dt.GetDataForRowField(parminfo[i].Name, row), parminfo[i].ParameterType); else toReturn[i] = BuildObject(dstore, dt, dstore.TypeInformationParser.GetTypeInfo(curr.ParameterType), row); } return toReturn; }
/// <summary> /// Builds a return object /// </summary> /// <param name="dstore">The datastore.</param> /// <param name="dt">The query data to build with</param> /// <param name="ti">The parsed type info for the object</param> /// <param name="i">The row in the result set to use</param> /// <returns></returns> public static object BuildObject(this IDataManager dstore, QueryData dt, TypeInfo ti, int i) { object toAdd; ConstructorInfo ci = ti.DataType.GetConstructor(new Type[] { }); object[] parms; if (ci == null) { ci = ti.DataType.GetConstructors().First(); ParameterInfo[] parminfo = ci.GetParameters(); toAdd = ci.Invoke(SetConstructorArguments(dstore, parminfo, ti, i, dt)); } else { parms = new object[0]; toAdd = ci.Invoke(parms); SetFieldData(dstore, ti, dt, i, toAdd); } return toAdd; }
/// <summary> /// Sets the fields on an object /// </summary> /// <param name="dstore">The datastore.</param> /// <param name="info">The information for the type</param> /// <param name="qd">The query data to use</param> /// <param name="row">The row to pull from</param> /// <param name="dataItem">The object to set the data on</param> public static void SetFieldData(this IDataManager dstore, TypeInfo info, QueryData qd, int row, object dataItem) { foreach (DataFieldInfo dfi in info.DataFields) { object item = qd.GetDataForRowField(dfi.FieldName, row); if (Convert.IsDBNull(item) && dfi.SetNull) { dfi.Setter(dataItem, dstore.Connection.TypeConverter.ConvertToType(item, dfi.PropertyType), null); } else if ((item != null && !Convert.IsDBNull(item)) || !dfi.PropertyType.IsSystemType()) { try { if (!dfi.PropertyType.IsSystemType()) dfi.Setter(dataItem, BuildObject(dstore, qd, dstore.TypeInformationParser.GetTypeInfo(dfi.PropertyType), row), null); else dfi.Setter(dataItem, dstore.Connection.TypeConverter.ConvertToType(item, dfi.PropertyType), null); } catch {//attempt to set to default ConstructorInfo ci = dfi.PropertyType.GetConstructors().Where(R => R.GetParameters().Count() == 0).FirstOrDefault(); if (ci != null) dfi.Setter(dataItem, ci.Invoke(null), null); } } } if (info.AdditionalInit != null) info.AdditionalInit.ForEach(R => R.Invoke(dstore, dataItem)); }
/// <summary> /// Sets the fields on an object /// </summary> /// <param name="dstore">The datastore.</param> /// <param name="qd">The query data to use</param> /// <param name="row">The row to pull from</param> /// <param name="dataItem">The object to set the data on</param> public static void SetFieldData(this IDataManager dstore, QueryData qd, int row, object dataItem) { TypeInfo ti = dstore.TypeInformationParser.GetTypeInfo(dataItem.GetType()); SetFieldData(dstore, ti, qd, row, dataItem); }
/// <summary> /// Executes a command and returns the result /// </summary> /// <param name="command">The command to execute</param> /// <param name="connection">The connection to use</param> /// <returns></returns> public virtual QueryData ExecuteCommandQuery(IDbCommand command, IDataConnection connection) { QueryData toReturn = new QueryData(); IDbConnection conn = connection.GetConnection(); if (conn.State != ConnectionState.Open) conn.Open(); if (connection.IsTransactional) command.Transaction = connection.GetTransaction; command.Connection = conn; command.CommandTimeout = 10000; IDataReader reader; try { FireEvent(command, connection); using (reader = command.ExecuteReader()) { if (!_mappings.ContainsKey(command.CommandText)) { _mappings[command.CommandText] = new Dictionary<string, int>(); DataTable schema = reader.GetSchemaTable(); if (schema != null) { for (int i = 0; i < schema.Rows.Count; i++) { _mappings[command.CommandText].Add(schema.Rows[i]["ColumnName"].ToString().ToUpper(), i); } } } toReturn.SetFieldMappings(_mappings[command.CommandText]); while (reader.Read()) { object[] values = new object[reader.FieldCount]; reader.GetValues(values); toReturn.AddRowData(values); } } } catch (Exception e) { //throw new QueryException(e, command); throw e; } finally { if (!connection.IsTransactional) conn.Close(); } toReturn.QuerySuccessful = true; return toReturn; }