/// <summary> /// Sets value of the specified <see cref="ResultProperty"/> on the target object /// when a 'resultMapping' attribute exists /// on the <see cref="ResultProperty"/>. /// </summary> /// <param name="request">The request.</param> /// <param name="resultMap">The result map.</param> /// <param name="mapping">The ResultProperty.</param> /// <param name="target">The target.</param> /// <param name="reader">The reader.</param> /// <param name="keys">The keys</param> public void Set(RequestScope request, IResultMap resultMap, ResultProperty mapping, ref object target, IDataReader reader, object keys) { object obj = Get(request, resultMap, mapping, ref target, reader); // Sets created object on the property resultMap.SetValueOfProperty( ref target, mapping, obj ); }
/// <summary> /// Gets the value of an argument constructor. /// </summary> /// <param name="request">The current <see cref="RequestScope"/>.</param> /// <param name="mapping">The <see cref="ResultProperty"/> with the argument infos.</param> /// <param name="reader">The current <see cref="IDataReader"/>.</param> /// <param name="keys">The keys</param> /// <returns>The paremeter value.</returns> public object GetValue(RequestScope request, ResultProperty mapping, ref IDataReader reader, object keys) { if (mapping.TypeHandler == null || mapping.TypeHandler is UnknownTypeHandler) // Find the TypeHandler { lock(mapping) { if (mapping.TypeHandler == null || mapping.TypeHandler is UnknownTypeHandler) { int columnIndex = 0; if (mapping.ColumnIndex == ResultProperty.UNKNOWN_COLUMN_INDEX) { columnIndex = reader.GetOrdinal(mapping.ColumnName); } else { columnIndex = mapping.ColumnIndex; } Type systemType =reader.GetFieldType(columnIndex); mapping.TypeHandler = request.DataExchangeFactory.TypeHandlerFactory.GetTypeHandler(systemType); } } } object dataBaseValue = mapping.GetDataBaseValue( reader ); request.IsRowDataFound = request.IsRowDataFound || (dataBaseValue != null); return dataBaseValue; }
/// <summary> /// Processes the specified <see cref="IDataReader"/> /// when a ResultMap is specified on the statement. /// </summary> /// <param name="request">The request.</param> /// <param name="reader">The reader.</param> /// <param name="resultObject">The result object.</param> public object Process(RequestScope request, ref IDataReader reader, object resultObject) { object outObject = resultObject; IResultMap resultMap = request.CurrentResultMap.ResolveSubMap(reader); if (outObject == null) { object[] parameters = null; if (resultMap.Parameters.Count > 0) { parameters = new object[resultMap.Parameters.Count]; // Fill parameters array for (int index = 0; index < resultMap.Parameters.Count; index++) { ResultProperty resultProperty = resultMap.Parameters[index]; parameters[index] = resultProperty.GetValue(request, ref reader, null); } } outObject = resultMap.CreateInstanceOfResult(parameters); } // For each Property in the ResultMap, set the property in the object for (int index = 0; index < resultMap.Properties.Count; index++) { ResultProperty property = resultMap.Properties[index]; property.PropertyStrategy.Set(request, resultMap, property, ref outObject, reader, null); } return outObject; }
///<summary> /// Sets value of the specified <see cref="ResultProperty"/> on the target object /// when a 'select' attribute exists and fills an <see cref="IList"/> property /// on the <see cref="ResultProperty"/> are empties. /// </summary> /// <param name="request">The request.</param> /// <param name="resultMap">The result map.</param> /// <param name="mapping">The ResultProperty.</param> /// <param name="target">The target.</param> /// <param name="reader">The current <see cref="IDataReader"/></param> /// <param name="keys">The keys</param> public void Set(RequestScope request, IResultMap resultMap, ResultProperty mapping, ref object target, IDataReader reader, object keys) { // Get the select statement IMappedStatement selectStatement = request.MappedStatement.ModelStore.GetMappedStatement(mapping.Select); PostBindind postSelect = new PostBindind(); postSelect.Statement = selectStatement; postSelect.Keys = keys; postSelect.Target = target; postSelect.ResultProperty = mapping; if (mapping.IsLazyLoad) { object values = mapping.LazyFactory.CreateProxy(request.MappedStatement.ModelStore.DataMapper, selectStatement, keys, target, mapping.SetAccessor); //为target类的mapping属性设置值为values mapping.Set(target, values); } else { if (mapping.SetAccessor.MemberType.GetGenericTypeDefinition() == typeof(IList<>)) { postSelect.Method = PostBindind.ExecuteMethod.ExecuteQueryForGenericIList; } //将postSelect类对象添加到队列中 request.DelayedLoad.Enqueue(postSelect); } }
///<summary> /// Sets value of the specified <see cref="ResultProperty"/> on the target object /// when a 'select' attribute exists and fills an object property. /// on the <see cref="ResultProperty"/> are empties. /// </summary> /// <param name="request">The request.</param> /// <param name="resultMap">The result map.</param> /// <param name="mapping">The ResultProperty.</param> /// <param name="target">The target.</param> /// <param name="reader">The current <see cref="IDataReader"/></param> /// <param name="keys">The keys</param> public void Set(RequestScope request, IResultMap resultMap, ResultProperty mapping, ref object target, IDataReader reader, object keys) { // Get the select statement IMappedStatement selectStatement = request.MappedStatement.ModelStore.GetMappedStatement(mapping.Select); PostBindind postSelect = new PostBindind(); postSelect.Statement = selectStatement; postSelect.Keys = keys; postSelect.Target = target; postSelect.ResultProperty = mapping; if (mapping.IsLazyLoad) { object values = mapping.LazyFactory.CreateProxy( request.MappedStatement.ModelStore.DataMapper, selectStatement, keys, target, mapping.SetAccessor); mapping.Set(target, values); } else { postSelect.Method = PostBindind.ExecuteMethod.ExecuteQueryForObject; request.DelayedLoad.Enqueue(postSelect); } }
/// <summary> /// Executes the specified <see cref="PostBindind"/>. /// </summary> /// <param name="postSelect">The <see cref="PostBindind"/>.</param> /// <param name="request">The <see cref="RequestScope"/></param> public void Execute(PostBindind postSelect, RequestScope request) { // How to: Examine and Instantiate Generic Types with Reflection // http://msdn2.microsoft.com/en-us/library/b8ytshk6.aspx //Type[] typeArgs = postSelect.ResultProperty.SetAccessor.MemberType.GetGenericArguments(); //Type genericList = typeof(IList<>); //Type constructedType = genericList.MakeGenericType(typeArgs); Type elementType = postSelect.ResultProperty.SetAccessor.MemberType.GetGenericArguments()[0]; Type mappedStatementType = postSelect.Statement.GetType(); //Type[] typeArguments = { typeof(ISession), typeof(object) }; MethodInfo[] mis = mappedStatementType.GetMethods(BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance); MethodInfo mi = null; for (int i = 0; i < mis.Length; i++) { if (mis[i].IsGenericMethod && mis[i].Name == "ExecuteQueryForList" && mis[i].GetParameters().Length == 2) { mi = mis[i]; break; } } MethodInfo miConstructed = mi.MakeGenericMethod(elementType); // Invoke the method. object[] args = { request.Session, postSelect.Keys }; object values = miConstructed.Invoke(postSelect.Statement, args); postSelect.ResultProperty.Set(postSelect.Target, values); }
/// <summary> /// Gets the value of the specified <see cref="ResultProperty"/> that must be set on the target object. /// </summary> /// <param name="request">The request.</param> /// <param name="resultMap">The result map.</param> /// <param name="mapping">The mapping.</param> /// <param name="target">The target.</param> /// <param name="reader">The reader.</param> /// <returns></returns> public object Get(RequestScope request, IResultMap resultMap, ResultProperty mapping, ref object target, IDataReader reader) { object result = null; IResultMap propertyRresultMap = mapping.NestedResultMap.ResolveSubMap(reader); string circularKey = GetCircularKey(propertyRresultMap, reader); // Gets the [key, result object] already build IDictionary<string, object> buildObjects = request.GetCirularKeys(propertyRresultMap); if (buildObjects != null && buildObjects.ContainsKey(circularKey)) { // circular key is already known, so get the existing result object result = buildObjects[circularKey]; } else if (circularKey == null || buildObjects == null || !buildObjects.ContainsKey(circularKey)) { // circular key is NOT known, so create a new result object. result = resultMapStrategy.Get(request, resultMap, mapping, ref target, reader); if (buildObjects == null) { buildObjects = new Dictionary<string, object>(); request.SetCirularKeys(propertyRresultMap, buildObjects); } buildObjects[circularKey] = result; } return result; }
/// <summary> /// Runs the query for for data table. /// </summary> /// <param name="request">The request.</param> /// <param name="session">The session.</param> /// <param name="parameterObject">The parameter object.</param> /// <returns></returns> internal DataTable RunQueryForDataTable(RequestScope request, ISession session, object parameterObject) { DataTable dataTable = new DataTable("DataTable"); using (IDbCommand command = request.IDbCommand) { IDataReader reader = command.ExecuteReader(); try { // Get Results while (reader.Read()) { DataRow dataRow = dataTable.NewRow(); dataTable.Rows.Add(dataRow); resultStrategy.Process(request, ref reader, dataRow); } } finally { reader.Close(); reader.Dispose(); } // do we need ?? //ExecuteDelayedLoad(request); // do we need ?? //RetrieveOutputParameters(request, session, command, parameterObject); } return dataTable; }
/// <summary> /// Executes the specified <see cref="PostBindind"/>. /// </summary> /// <param name="postSelect">The <see cref="PostBindind"/>.</param> /// <param name="request">The <see cref="RequestScope"/></param> public void Execute(PostBindind postSelect, RequestScope request) { IFactory factory = request.DataExchangeFactory.ObjectFactory.CreateFactory(postSelect.ResultProperty.SetAccessor.MemberType, Type.EmptyTypes); object values = factory.CreateInstance(null); postSelect.Statement.ExecuteQueryForList(request.Session, postSelect.Keys, (IList)values); postSelect.ResultProperty.Set(postSelect.Target, values); }
///<summary> /// Sets value of the specified <see cref="ResultProperty"/> on the target object /// when the 'select' and 'resultMap' attributes /// on the <see cref="ResultProperty"/> are empties. /// </summary> /// <param name="request">The request.</param> /// <param name="resultMap">The result map.</param> /// <param name="mapping">The ResultProperty.</param> /// <param name="target">The target.</param> /// <param name="reader">The reader.</param> /// <param name="keys">The keys</param> public void Set(RequestScope request, IResultMap resultMap, ResultProperty mapping, ref object target, IDataReader reader, object keys) { //获取属性mapping的值 object obj = Get(request, resultMap, mapping, ref target, reader); //将mapping的值放到类中对应的属性里 resultMap.SetValueOfProperty(ref target, mapping, obj); }
/// <summary> /// Processes the specified <see cref="IDataReader"/>. /// </summary> /// <param name="request">The request.</param> /// <param name="reader">The reader.</param> /// <param name="resultObject">The result object.</param> /// <returns>The result object</returns> public object Process(RequestScope request, ref IDataReader reader, object resultObject) { object outObject = resultObject; //实现对当前CurrentResultMap类中的discrimitor子节点类的设置 IResultMap resultMap = request.CurrentResultMap.ResolveSubMap(reader); //获取resultMap分组名对应的值 string uniqueKey = GetUniqueKey(resultMap, reader); // Gets the [key, result object] already build //根据IResultMap获取对应的IDictionary IDictionary<string, object> buildObjects = request.GetUniqueKeys(resultMap); if (buildObjects != null && buildObjects.ContainsKey(uniqueKey)) { // Unique key is already known, so get the existing result object and process additional results. outObject = buildObjects[uniqueKey]; // process resulMapping attribute which point to a groupBy attribute //遍历resultMap.Properties属性中为GroupByStrategy的属性 for (int index = 0; index < resultMap.Properties.Count; index++) { ResultProperty resultProperty = resultMap.Properties[index]; if (resultProperty.PropertyStrategy is PropertStrategy.GroupByStrategy) { //.................??? 跳到PropertyStrategy中的GroupByStrategy类 resultProperty.PropertyStrategy.Set(request, resultMap, resultProperty, ref outObject, reader, null); } } outObject = SKIP; } else if (uniqueKey == null || buildObjects == null || !buildObjects.ContainsKey(uniqueKey)) { // Unique key is NOT known, so create a new result object and process additional results. // Fix IBATISNET-241 if (outObject == null) { // temp ?, we don't support constructor tag with groupBy attribute outObject = resultMap.CreateInstanceOfResult(null);//创建返回类的对象 } for (int index = 0; index < resultMap.Properties.Count; index++) { ResultProperty resultProperty = resultMap.Properties[index]; //为当前的resultProperty属性设置其从数据库中读到的值到outObject类中 resultProperty.PropertyStrategy.Set(request, resultMap, resultProperty, ref outObject, reader, null); } if (buildObjects == null) { buildObjects = new Dictionary<string, object>(); request.SetUniqueKeys(resultMap, buildObjects); } buildObjects[uniqueKey] = outObject; } return outObject; }
/// <summary> /// Gets the value of an argument constructor. /// </summary> /// <param name="request">The current <see cref="RequestScope"/>.</param> /// <param name="mapping">The <see cref="ResultProperty"/> with the argument infos.</param> /// <param name="reader">The current <see cref="IDataReader"/>.</param> /// <param name="keys">The keys</param> /// <returns>The paremeter value.</returns> public object GetValue(RequestScope request, ResultProperty mapping, ref IDataReader reader, object keys) { // Get the select statement IMappedStatement selectStatement = request.MappedStatement.ModelStore.GetMappedStatement(mapping.Select); reader = DataReaderTransformer.Transform(reader, request.Session.SessionFactory.DataSource.DbProvider); return selectStatement.ExecuteQueryForObject(request.Session, keys, null); }
/// <summary> /// Processes the specified <see cref="IDataReader"/>. /// </summary> /// <param name="request">The request.</param> /// <param name="reader">The reader.</param> /// <param name="resultObject">The result object.</param> /// <returns>The result object</returns> public object Process(RequestScope request, ref IDataReader reader, object resultObject) { object outObject = resultObject; IResultMap resultMap = request.CurrentResultMap.ResolveSubMap(reader); string uniqueKey = GetUniqueKey(resultMap, reader); // Gets the [key, result object] already build IDictionary<string, object> buildObjects = request.GetUniqueKeys(resultMap); if (buildObjects != null && buildObjects.ContainsKey(uniqueKey)) { // Unique key is already known, so get the existing result object and process additional results. outObject = buildObjects[uniqueKey]; // process resulMapping attribute which point to a groupBy attribute for (int index = 0; index < resultMap.Properties.Count; index++) { ResultProperty resultProperty = resultMap.Properties[index]; if (resultProperty.PropertyStrategy is PropertStrategy.GroupByStrategy) { resultProperty.PropertyStrategy.Set(request, resultMap, resultProperty, ref outObject, reader, null); } } outObject = SKIP; } else if (uniqueKey == null || buildObjects == null || !buildObjects.ContainsKey(uniqueKey)) { // Unique key is NOT known, so create a new result object and process additional results. // Fix IBATISNET-241 if (outObject == null) { // temp ?, we don't support constructor tag with groupBy attribute outObject = resultMap.CreateInstanceOfResult(null); } for (int index = 0; index < resultMap.Properties.Count; index++) { ResultProperty resultProperty = resultMap.Properties[index]; resultProperty.PropertyStrategy.Set(request, resultMap, resultProperty, ref outObject, reader, null); } if (buildObjects == null) { buildObjects = new Dictionary<string, object>(); request.SetUniqueKeys(resultMap, buildObjects); } buildObjects[uniqueKey] = outObject; } return outObject; }
/// <summary> /// Processes the specified <see cref="IDataReader"/>. /// </summary> /// <param name="request">The request.</param> /// <param name="reader">The reader.</param> /// <param name="resultObject">The result object.</param> /// <returns></returns> public object Process(RequestScope request, ref IDataReader reader, object resultObject) { object outObject = resultObject; IResultMap resultMap = request.CurrentResultMap.ResolveSubMap(reader); string circularKey = GetCircularKey(resultMap, reader); // Gets the [key, result object] already build IDictionary<string, object> buildObjects = request.GetCirularKeys(resultMap); if (buildObjects != null && buildObjects.ContainsKey(circularKey)) { // circular key is already known, so get the existing result object outObject = buildObjects[circularKey]; } else if (circularKey == null || buildObjects == null || !buildObjects.ContainsKey(circularKey)) { // circular key is NOT known, so create a new result object. if (outObject == null) { object[] parameters = null; if (resultMap.Parameters.Count > 0) { parameters = new object[resultMap.Parameters.Count]; // Fill parameters array for (int index = 0; index < resultMap.Parameters.Count; index++) { ResultProperty resultProperty = resultMap.Parameters[index]; parameters[index] = resultProperty.GetValue(request, ref reader, null); } } outObject = resultMap.CreateInstanceOfResult(parameters); } // For each Property in the ResultMap, set the property in the object for (int index = 0; index < resultMap.Properties.Count; index++) { ResultProperty resultProperty = resultMap.Properties[index]; resultProperty.PropertyStrategy.Set(request, resultMap, resultProperty, ref outObject, reader, null); } if (buildObjects == null) { buildObjects = new Dictionary<string, object>(); request.SetCirularKeys(resultMap, buildObjects); } buildObjects[circularKey] = outObject; } return outObject; }
/// <summary> /// Executes the specified <see cref="PostBindind"/>. /// </summary> /// <param name="postSelect">The <see cref="PostBindind"/>.</param> /// <param name="request">The <see cref="RequestScope"/></param> public void Execute(PostBindind postSelect, RequestScope request) { IList values = postSelect.Statement.ExecuteQueryForList(request.Session, postSelect.Keys); Type elementType = postSelect.ResultProperty.SetAccessor.MemberType.GetElementType(); Array array = Array.CreateInstance(elementType, values.Count); int count = values.Count; for(int i=0;i<count;i++) { array.SetValue(values[i],i); } postSelect.ResultProperty.Set(postSelect.Target, array); }
/// <summary> /// Create an IDbCommand for the current session and statement then fill in its IDataParameters based on parameterObject. /// </summary> /// <param name="request"></param> /// <param name="session">The SqlMapSession</param> /// <param name="statement">The IStatement</param> /// <param name="parameterObject"> /// The parameter object that will fill the sql parameter /// </param> /// <remarks> /// The constructed IDbCommand is available from request.IDbCommand /// </remarks> public void Create(RequestScope request, ISession session, IStatement statement, object parameterObject ) { // the IDbConnection & the IDbTransaction are assign in the CreateCommand IDbProvider dbProvider = session.SessionFactory.DataSource.DbProvider; request.IDbCommand = new DbCommandDecorator(CreateCommandAndEnlistTransaction(dbProvider, statement.CommandType, session), request); request.IDbCommand.CommandText = request.PreparedStatement.PreparedSql; if (log.IsDebugEnabled) { log.Debug("Preparing to apply parameter information to Statement Id: [" + statement.Id + "] based off of PreparedStatement: [" + request.IDbCommand.CommandText + "]"); } ApplyParameterMap( session.SessionFactory.DataSource.DbProvider , request.IDbCommand, request, statement, parameterObject ); }
/// <summary> /// Processes the specified <see cref="IDataReader"/> /// when a ResultClass is specified on the statement and /// the ResultClass is a SimpleType. /// </summary> /// <param name="request">The request.</param> /// <param name="reader">The reader.</param> /// <param name="resultObject">The result object.</param> public object Process(RequestScope request, ref IDataReader reader, object resultObject) { object outObject = resultObject; AutoResultMap resultMap = (AutoResultMap)request.CurrentResultMap; if (outObject == null) { outObject = resultMap.CreateInstanceOfResult(null); } if (!resultMap.IsInitalized) { lock(resultMap) { if (!resultMap.IsInitalized) { // Create a ResultProperty const string propertyName = "value"; const int columnIndex = 0; ITypeHandler typeHandler = request.DataExchangeFactory.TypeHandlerFactory.GetTypeHandler(outObject.GetType()); ResultProperty property = new ResultProperty( propertyName, string.Empty, columnIndex, string.Empty, string.Empty, string.Empty, false, string.Empty, null, string.Empty, null, null, typeHandler); //property.PropertyStrategy = PropertyStrategyFactory.Get(property); resultMap.Properties.Add(property); resultMap.DataExchange = request.DataExchangeFactory.GetDataExchangeForClass(typeof(int));// set the PrimitiveDataExchange resultMap.IsInitalized = true; } } } //为outObject类的属性property赋值 resultMap.Properties[0].PropertyStrategy.Set(request, resultMap, resultMap.Properties[0], ref outObject, reader, null); return outObject; }
/// <summary> /// Gets the value of an argument constructor. /// </summary> /// <param name="request">The current <see cref="RequestScope"/>.</param> /// <param name="mapping">The <see cref="ResultProperty"/> with the argument infos.</param> /// <param name="reader">The current <see cref="IDataReader"/>.</param> /// <param name="keys">The keys</param> /// <returns>The paremeter value.</returns> public object GetValue(RequestScope request, ResultProperty mapping, ref IDataReader reader, object keys) { // Get the select statement IMappedStatement selectStatement = request.MappedStatement.ModelStore.GetMappedStatement(mapping.Select); if (mapping.MemberType == typeof(IList)) { reader = DataReaderTransformer.Transform(reader, request.Session.SessionFactory.DataSource.DbProvider); return selectStatement.ExecuteQueryForList(request.Session, keys); } reader = DataReaderTransformer.Transform(reader, request.Session.SessionFactory.DataSource.DbProvider); IFactory factory = request.DataExchangeFactory.ObjectFactory.CreateFactory(mapping.MemberType, Type.EmptyTypes); object values = factory.CreateInstance(null); selectStatement.ExecuteQueryForList(request.Session, keys, (IList)values); return values; }
/// <summary> /// Processes the specified <see cref="IDataReader"/> /// when a 'resultClass' attribute is specified on the statement and /// the 'resultClass' attribute is a <see cref="IDictionary"/>. /// </summary> /// <param name="request">The request.</param> /// <param name="reader">The reader.</param> /// <param name="resultObject">The result object.</param> public object Process(RequestScope request, ref IDataReader reader, object resultObject) { object outObject = resultObject; //AutoResultMap resultMap = request.CurrentResultMap as AutoResultMap; if (outObject == null) { outObject = request.CurrentResultMap.CreateInstanceOfResult(null); } int count = reader.FieldCount; IDictionary dictionary = (IDictionary) outObject; for (int i = 0; i < count; i++) { //ResultProperty property = new ResultProperty(); //property.PropertyName = "value"; //property.ColumnIndex = i; //property.TypeHandler = request.DataExchangeFactory.TypeHandlerFactory.GetTypeHandler(reader.GetFieldType(i)); const string propertyName = "value"; int columnIndex = i; ITypeHandler typeHandler = request.DataExchangeFactory.TypeHandlerFactory.GetTypeHandler(reader.GetFieldType(i)); ResultProperty property = new ResultProperty( propertyName, string.Empty, columnIndex, string.Empty, string.Empty, string.Empty, false, string.Empty, null, string.Empty, typeof(IDictionary), request.DataExchangeFactory, typeHandler); dictionary.Add( reader.GetName(i), property.GetDataBaseValue(reader)); } return outObject; }
/// <summary> /// Processes the specified <see cref="IDataReader"/>. /// </summary> /// <param name="request">The request.</param> /// <param name="reader">The reader.</param> /// <param name="resultObject">The result object.</param> public object Process(RequestScope request, ref IDataReader reader, object resultObject) { IResultMap resultMap = request.CurrentResultMap.ResolveSubMap(reader); if (resultMap.GroupByPropertyNames.Count>0) { return groupByStrategy.Process(request, ref reader, resultObject); } if (resultMap.KeyPropertyNames.Count > 0) { return cirularStrategy.Process(request, ref reader, resultObject); } if (typeof(DataRow).IsAssignableFrom(resultMap.Class)) { return dataTableStrategy.Process(request, ref reader, resultObject); } return resultMapStrategy.Process(request, ref reader, resultObject); }
/// <summary> /// Gets the value of an argument constructor. /// </summary> /// <param name="request">The current <see cref="RequestScope"/>.</param> /// <param name="mapping">The <see cref="ResultProperty"/> with the argument infos.</param> /// <param name="reader">The current <see cref="IDataReader"/>.</param> /// <param name="keys">The keys</param> /// <returns>The paremeter value.</returns> public object GetValue(RequestScope request, ResultProperty mapping, ref IDataReader reader, object keys) { // Get the select statement IMappedStatement selectStatement = request.MappedStatement.ModelStore.GetMappedStatement(mapping.Select); reader = DataReaderTransformer.Transform(reader, request.Session.SessionFactory.DataSource.DbProvider); IList values = selectStatement.ExecuteQueryForList(request.Session, keys); Type elementType = mapping.MemberType.GetElementType(); Array array = Array.CreateInstance(elementType, values.Count); int count = values.Count; for(int i=0;i<count;i++) { array.SetValue(values[i],i); } return array; }
///<summary> /// Sets value of the specified <see cref="ResultProperty"/> on the target object /// when a 'select' attribute exists and fills an Array property /// on the <see cref="ResultProperty"/> are empties. /// </summary> /// <param name="request">The request.</param> /// <param name="resultMap">The result map.</param> /// <param name="mapping">The ResultProperty.</param> /// <param name="target">The target.</param> /// <param name="reader">The <see cref="IDataReader"/></param> /// <param name="keys">The keys</param> public void Set(RequestScope request, IResultMap resultMap, ResultProperty mapping, ref object target, IDataReader reader, object keys) { // Get the select statement IMappedStatement selectStatement = request.MappedStatement.ModelStore.GetMappedStatement(mapping.Select); PostBindind postSelect = new PostBindind(); postSelect.Statement = selectStatement; postSelect.Keys = keys; postSelect.Target = target; postSelect.ResultProperty = mapping; if (mapping.IsLazyLoad) { throw new NotImplementedException("Lazy load no supported for System.Array property:" + mapping.SetAccessor.Name); } postSelect.Method = PostBindind.ExecuteMethod.ExecuteQueryForArrayList; request.DelayedLoad.Enqueue(postSelect); }
/// <summary> /// Check if the specify object is equal to the current object. /// </summary> /// <param name="obj"></param> /// <returns></returns> public override bool Equals(object obj) { if (this == obj) { return(true); } if (!(obj is RequestScope)) { return(false); } RequestScope scope = (RequestScope)obj; if (id != scope.id) { return(false); } return(true); }
/// <summary> /// Processes the specified <see cref="IDataReader"/>. /// </summary> /// <param name="request">The request.</param> /// <param name="reader">The reader.</param> /// <param name="resultObject">The result object.</param> public object Process(RequestScope request, ref IDataReader reader, object resultObject) { // Check if the ResultClass is a 'primitive' Type if (request.DataExchangeFactory.TypeHandlerFactory.IsSimpleType(request.CurrentResultMap.Class)) { return simpleTypeStrategy.Process(request, ref reader, resultObject); } if (typeof(IDictionary).IsAssignableFrom(request.CurrentResultMap.Class)) { return dictionaryStrategy.Process(request, ref reader, resultObject); } if (typeof(IList).IsAssignableFrom(request.CurrentResultMap.Class)) { return listStrategy.Process(request, ref reader, resultObject); } if (typeof(DataRow).IsAssignableFrom(request.CurrentResultMap.Class)) { return dataTableStrategy.Process(request, ref reader, resultObject); } return autoMapStrategy.Process(request, ref reader, resultObject); }
/// <summary> /// Fills the object with reader and result map. /// </summary> /// <param name="request">The request.</param> /// <param name="reader">The reader.</param> /// <param name="resultMap">The result map.</param> /// <param name="resultObject">The result object.</param> /// <returns>Indicates if we have found a row.</returns> protected static bool FillObjectWithReaderAndResultMap(RequestScope request,IDataReader reader, IResultMap resultMap, ref object resultObject) { bool dataFound = false; if (resultMap.Properties.Count>0) { // For each Property in the ResultMap, set the property in the object for(int index=0; index< resultMap.Properties.Count; index++) { request.IsRowDataFound = false; ResultProperty property = resultMap.Properties[index]; property.PropertyStrategy.Set(request, resultMap, property, ref resultObject, reader, null); dataFound = dataFound || request.IsRowDataFound; } request.IsRowDataFound = dataFound; return dataFound; } return true; }
/// <summary> /// Initializes a new instance of the <see cref="PreparedStatementFactory"/> class. /// </summary> /// <param name="session">The session.</param> /// <param name="dbHelperParameterCache">The db helper parameter cache.</param> /// <param name="request">The request.</param> /// <param name="statement">The statement.</param> /// <param name="commandText">The command text.</param> public PreparedStatementFactory( ISession session, DBHelperParameterCache dbHelperParameterCache, RequestScope request, IStatement statement, string commandText) { Contract.Require.That(session, Is.Not.Null).When("retrieving argument session using statement '" + statement.Id + "' in PreparedStatementFactory constructor"); Contract.Require.That(dbHelperParameterCache, Is.Not.Null).When("retrieving argument dBHelperParameterCache using statement '" + statement.Id + "' in PreparedStatementFactory constructor"); Contract.Require.That(request, Is.Not.Null).When("retrieving argument request using statement '" + statement.Id + "' in PreparedStatementFactory constructor"); Contract.Require.That(statement, Is.Not.Null).When("retrieving argument statement using statement '" + statement.Id + "' in PreparedStatementFactory constructor"); Contract.Require.That(commandText, Is.Not.Null & Is.Not.Empty).When("retrieving argument commandText using statement '" + statement.Id + "' in PreparedStatementFactory constructor"); this.session = session; this.request = request; this.statement = statement; this.commandText = commandText; this.dbHelperParameterCache = dbHelperParameterCache; dbProvider = session.SessionFactory.DataSource.DbProvider; parameterPrefix = dbProvider.ParameterPrefix; }
/// <summary> /// Gets the value of the specified <see cref="ResultProperty"/> that must be set on the target object. /// </summary> /// <param name="request">The request.</param> /// <param name="resultMap">The result map.</param> /// <param name="mapping">The mapping.</param> /// <param name="reader">The reader.</param> /// <param name="target">The target object</param> public object Get(RequestScope request, IResultMap resultMap, ResultProperty mapping, ref object target, IDataReader reader) { object[] parameters = null; bool isParameterFound = false; IResultMap resultMapping = mapping.NestedResultMap.ResolveSubMap(reader); if (resultMapping.Parameters.Count > 0) { parameters = new object[resultMapping.Parameters.Count]; // Fill parameters array for (int index = 0; index < resultMapping.Parameters.Count; index++) { ResultProperty resultProperty = resultMapping.Parameters[index]; parameters[index] = resultProperty.GetValue(request, ref reader, null); request.IsRowDataFound = request.IsRowDataFound || (parameters[index] != null); isParameterFound = isParameterFound || (parameters[index] != null); } } object obj = null; // If I have a constructor tag and all argumments values are null, the obj is null if (resultMapping.Parameters.Count > 0 && isParameterFound == false) { obj = null; } else { obj = resultMapping.CreateInstanceOfResult(parameters); // Fills properties on the new object if (FillObjectWithReaderAndResultMap(request, reader, resultMapping, ref obj) == false) { obj = null; } } return obj; }
/// <summary> /// Gets the value of an argument constructor. /// </summary> /// <param name="request">The current <see cref="RequestScope"/>.</param> /// <param name="mapping">The <see cref="ResultProperty"/> with the argument infos.</param> /// <param name="reader">The current <see cref="IDataReader"/>.</param> /// <param name="keys">The keys</param> /// <returns>The paremeter value.</returns> public object GetValue(RequestScope request, ResultProperty mapping, ref IDataReader reader, object keys) { // Get the select statement IMappedStatement selectStatement = request.MappedStatement.ModelStore.GetMappedStatement(mapping.Select); reader = DataReaderTransformer.Transform(reader, request.Session.SessionFactory.DataSource.DbProvider); //Type[] typeArgs = mapping.MemberType.GetGenericArguments(); //Type genericList = typeof(IList<>); //Type constructedType = genericList.MakeGenericType(typeArgs); Type elementType = mapping.MemberType.GetGenericArguments()[0]; Type mappedStatementType = selectStatement.GetType(); //Type[] typeArguments = { typeof(ISession), typeof(object) }; MethodInfo[] mis = mappedStatementType.GetMethods(BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance); MethodInfo mi = null; for (int i = 0; i < mis.Length; i++) { if (mis[i].IsGenericMethod && mis[i].Name == "ExecuteQueryForList" && mis[i].GetParameters().Length == 2) { mi = mis[i]; break; } } MethodInfo miConstructed = mi.MakeGenericMethod(elementType); // Invoke the method. object[] args = { request.Session, keys }; object values = miConstructed.Invoke(selectStatement, args); return values; }
/// <summary> /// Auto-map the reader to the result object. /// </summary> /// <param name="request">The request.</param> /// <param name="reader">The reader.</param> /// <param name="resultObject">The result object.</param> /// <returns>The AutoResultMap use to map the resultset.</returns> private static AutoResultMap InitializeAutoResultMap(RequestScope request, IDataReader reader, ref object resultObject) { AutoResultMap resultMap = request.CurrentResultMap as AutoResultMap; if (request.Statement.AllowRemapping) { resultMap = resultMap.Clone(); //根据reader的字段从resultObject类中获取对应的属性类集合 ResultPropertyCollection properties = ReaderAutoMapper.Build( request.DataExchangeFactory, reader, ref resultObject); resultMap.Properties.AddRange(properties); } else { if (!resultMap.IsInitalized) { lock (resultMap) { if (!resultMap.IsInitalized) { ResultPropertyCollection properties = ReaderAutoMapper.Build( request.DataExchangeFactory, reader, ref resultObject); resultMap.Properties.AddRange(properties); resultMap.IsInitalized = true; } } } } return resultMap; }
/// <summary> /// Processes the specified <see cref="IDataReader"/> /// when a ResultClass is specified on the statement and /// the ResultClass is <see cref="IList"/>. /// </summary> /// <param name="request">The request.</param> /// <param name="reader">The reader.</param> /// <param name="resultObject">The result object.</param> public object Process(RequestScope request, ref IDataReader reader, object resultObject) { object outObject = resultObject; //AutoResultMap resultMap = request.CurrentResultMap as AutoResultMap; if (outObject == null) { outObject = request.CurrentResultMap.CreateInstanceOfResult(null); } //将reader当前行中的所有字段加入到IList对象中 int count = reader.FieldCount; for (int i = 0; i < count; i++) { const string propertyName = "value"; int columnIndex = i; ITypeHandler typeHandler = request.DataExchangeFactory.TypeHandlerFactory.GetTypeHandler(reader.GetFieldType(i)); ResultProperty property = new ResultProperty( propertyName, string.Empty, columnIndex, string.Empty, string.Empty, string.Empty, false, string.Empty, null, string.Empty, null, null, typeHandler); ((IList) outObject).Add(property.GetDataBaseValue(reader)); } return outObject; }
/// <summary> /// Build the PreparedStatement /// </summary> /// <param name="session">The session.</param> /// <param name="request">The request.</param> /// <param name="sql">The SQL.</param> /// <returns></returns> private PreparedStatement BuildPreparedStatement(ISession session, RequestScope request, string sql) { PreparedStatementFactory factory = new PreparedStatementFactory( session, dbHelperParameterCache, request, statement, sql); return factory.Prepare(false); }