public override object GetSetMemberValue(object value) { // Bug workaround for Spring: if ((value != null) && ((value is string) || (value is char))) { string valueString = value.ToString(); if ((valueString.Length == 0) || (valueString == "\0")) { value = null; } } if (value is DBNull) { value = null; } else if (m_IsDbBoolString) { if (((value == null) && (m_IsSpecifiedMemberInfo == null)) || string.Equals(value.ToString(), "N", StringComparison.InvariantCultureIgnoreCase)) { value = false; } else if (string.Equals(value.ToString(), "Y", StringComparison.InvariantCultureIgnoreCase)) { value = true; } else { throw new MappingException("Invalid boolean string valid specified (\"{0}\") for column: {1}", value, this.ToString()); } } else if (m_IsDecimalString) { if (value != null) { string valueStr = value.ToString(); ; if (valueStr.IndexOf('.') > 0) { valueStr = valueStr.TrimEnd('0').TrimEnd('.'); } value = valueStr; } } else if (m_IsTenDigitDateString) { } else if (m_IsTimeType) { if (value != null) { if (m_MemberType == typeof(string)) { DateTime existingValue = (DateTime)value; value = existingValue.ToString("HH:mm:ss"); } else { DateTime existingValue = (DateTime)value; value = new DateTime(1900, 1, 1, existingValue.Hour, existingValue.Minute, existingValue.Second); } } } else if (m_IsCustomXmlStringFormatType) { if (value != null) { CustomXmlStringFormatTypeBase newValue = (CustomXmlStringFormatTypeBase)Activator.CreateInstance(m_MemberType); try { newValue.SetValue(value); } catch (Exception ex) { throw new ArgException("Failed to convert the database value \"{0}\" of type \"{1}\" to type \"{2}\" for column \"{3}.{4}\" with exception: {5}", value, value.GetType().Name, m_MemberType.Name, this.Table.TableName, this.ColumnName, ExceptionUtils.GetDeepExceptionMessage(ex)); } value = newValue; } } return(base.GetSetMemberValue(value)); }
protected virtual Dictionary <object, IList> LoadObjectInstancesToList(Table tableOfObjectsToLoad, Dictionary <object, object> parentPKToObjectMap, IDictionary <string, DbAppendSelectWhereClause> appendSelectWhereClauseMap, ColumnCachedValues cachedValues, MappingContext mappingContext, IDbCommand command) { Dictionary <object, IList> list = null; Dictionary <object, bool> anyInstanceFieldsWereSetMap = null; Dictionary <object, object> pkToObjectMap = null; bool isVirtualObjectTable = tableOfObjectsToLoad.IsVirtualTable; bool isCustomXmlStringFormatTypeTable = false; if (isVirtualObjectTable) { isCustomXmlStringFormatTypeTable = tableOfObjectsToLoad.TableRootType.IsSubclassOf(typeof(CustomXmlStringFormatTypeBase)); } using (IDataReader reader = command.ExecuteReader()) { while (reader.Read()) { int readerIndex = 0; object pk = null, fk = null, pkKey = null, fkKey = null; bool skip = false; bool anyObjectToSetFieldsWereSet = false; Column pkColumn = null, fkColumn = null; object objectToSet = null; // isVirtualObjectTable == true if this table represents a string[], int[], etc. member foreach (Column column in tableOfObjectsToLoad.DirectColumns) { if (!column.NoLoad) { object value = reader.GetValue(readerIndex++); if (value == DBNull.Value) { value = null; } if (column.IsPrimaryKey) { pkKey = value + "_" + tableOfObjectsToLoad.TableName; pkColumn = column; pk = value; } else if (column.IsForeignKey) { if (value != null) { fkKey = value + "_" + ((ForeignKeyColumn)column).ForeignTable.TableName; if (fkColumn != null) { if (pk != null) { throw new ArgException("The table \"{0}\" has a row with a primary key of \"{1}\" that has more than one foreign key specified. Please specify only one foreign key per row for this table.", column.Table.TableName, pk.ToString()); } else { throw new ArgException("The table \"{0}\" has a row that has more than one foreign key specified. Please specify only one foreign key per row for this table.", column.Table.TableName); } } if (!parentPKToObjectMap.ContainsKey(fkKey)) { // This object has no parent, assume we skip it skip = true; break; } fkColumn = column; fk = value; } } else { if (value != null) { if (isVirtualObjectTable) { if (isCustomXmlStringFormatTypeTable) { CustomXmlStringFormatTypeBase newObjectToSet = (CustomXmlStringFormatTypeBase)Activator.CreateInstance(tableOfObjectsToLoad.TableRootType); newObjectToSet.SetValue(value); objectToSet = newObjectToSet; } else { objectToSet = column.GetSetMemberValue(value); } } else { if (objectToSet == null) { objectToSet = Activator.CreateInstance(tableOfObjectsToLoad.TableRootType); } column.SetSelectColumnValue(objectToSet, value, cachedValues); anyObjectToSetFieldsWereSet = true; } } } } } if (skip) { continue; } if (objectToSet == null) { objectToSet = Activator.CreateInstance(tableOfObjectsToLoad.TableRootType); } ExceptionUtils.ThrowIfNull(pkColumn, "pkColumn"); ExceptionUtils.ThrowIfNull(pk, "pk"); if (!isVirtualObjectTable) { pkColumn.SetSelectColumnValue(objectToSet, pk, cachedValues); if (fkColumn != null) { fkColumn.SetSelectColumnValue(objectToSet, fk, cachedValues); } else { if (parentPKToObjectMap != null) { throw new ArgException("The table \"{0}\" has a row with a primary key of \"{1}\" that does not have a foreign key specified.", pkColumn.Table.TableName, pk.ToString()); } fk = pk; fkKey = pkKey; } if (mappingContext.UseNewSameTableMapping) { LoadSameTableInstancesNew(objectToSet, tableOfObjectsToLoad.ChildSameTableElements, cachedValues, reader, ref readerIndex, ref anyObjectToSetFieldsWereSet); } else { LoadSameTableInstances(objectToSet, tableOfObjectsToLoad.ChildSameTableElements, cachedValues, reader, ref readerIndex, ref anyObjectToSetFieldsWereSet); } } int fieldCount = reader.FieldCount; if (readerIndex != fieldCount) { throw new IndexOutOfRangeException(string.Format("The number of selected column values ({0}) is less than the expected number ({1}) for the object \"{2}\" and sql \"{3}\".", reader.FieldCount.ToString(), readerIndex.ToString(), tableOfObjectsToLoad.TableRootType.Name, tableOfObjectsToLoad.SelectSql)); } if (list == null) { list = new Dictionary <object, IList>(); pkToObjectMap = new Dictionary <object, object>(); anyInstanceFieldsWereSetMap = new Dictionary <object, bool>(); } IList listInstance; if (!list.TryGetValue(fkKey, out listInstance)) { listInstance = (IList)Activator.CreateInstance(typeof(List <>).MakeGenericType(tableOfObjectsToLoad.TableRootType)); list.Add(fkKey, listInstance); } try { listInstance.Add(objectToSet); } catch (Exception) { throw; } if (!isVirtualObjectTable) { pkToObjectMap.Add(pkKey, objectToSet); anyInstanceFieldsWereSetMap.Add(objectToSet, anyObjectToSetFieldsWereSet); } } } if (!isVirtualObjectTable) { if (list != null) { // Load children if (tableOfObjectsToLoad.ChildRelationMembers != null) { foreach (ChildRelationInfo childRelation in tableOfObjectsToLoad.ChildRelationMembers) { Table elementTable = null; if (Utils.IsValidColumnType(childRelation.ValueType)) { elementTable = childRelation.ChildTable; } if (childRelation.IsOneToMany) { Dictionary <object, IList> fkMap = LoadObjectInstancesToList(childRelation.ValueType, elementTable, pkToObjectMap, appendSelectWhereClauseMap, cachedValues, mappingContext, command); if (fkMap != null) { foreach (KeyValuePair <object, IList> pair in fkMap) { object objectToSet = pkToObjectMap[pair.Key]; if (childRelation.ParentToMemberChain != null) { foreach (SameTableElementInfo sameTableElementInfo in childRelation.ParentToMemberChain) { object childObjectToSet = sameTableElementInfo.GetMemberValue(objectToSet); if (childObjectToSet == null) { childObjectToSet = Activator.CreateInstance(sameTableElementInfo.MemberType); } objectToSet = childObjectToSet; } } DebugUtils.AssertDebuggerBreak(pair.Value != null); childRelation.SetMemberValue(objectToSet, pair.Value); anyInstanceFieldsWereSetMap[objectToSet] = true; } } } else // One to one { Dictionary <object, IList> fkMap = LoadObjectInstancesToList(childRelation.ValueType, elementTable, pkToObjectMap, appendSelectWhereClauseMap, cachedValues, mappingContext, command); if (fkMap != null) { foreach (KeyValuePair <object, IList> pair in fkMap) { if (pair.Value.Count != 1) { throw new InvalidOperationException(string.Format("Relation is One-To-One but got more than one element: {0}", childRelation.ToString())); } object itemToSet = CollectionUtils.FirstItem(pair.Value); DebugUtils.AssertDebuggerBreak(itemToSet != null); object objectToSet = pkToObjectMap[pair.Key]; if (childRelation.ParentToMemberChain != null) { foreach (SameTableElementInfo sameTableElementInfo in childRelation.ParentToMemberChain) { object childObjectToSet = sameTableElementInfo.GetMemberValue(objectToSet); if (childObjectToSet == null) { childObjectToSet = Activator.CreateInstance(sameTableElementInfo.MemberType); } objectToSet = childObjectToSet; } } childRelation.SetMemberValue(objectToSet, itemToSet); anyInstanceFieldsWereSetMap[objectToSet] = true; } } } } } } } #if REMOVE_EMPTY_OBJECTS if (list != null) { List <string> removeKeys = new List <string>(); foreach (KeyValuePair <string, IList> pair in list) { if (pair.Value != null) { for (int i = pair.Value.Count - 1; i >= 0; --i) { object checkObject = pair.Value[i]; if (!anyInstanceFieldsWereSetMap[checkObject]) { pair.Value.RemoveAt(i); } } } if (CollectionUtils.IsNullOrEmpty(pair.Value)) { removeKeys.Add(pair.Key); } } foreach (string removeKey in removeKeys) { list.Remove(removeKey); } } #endif // REMOVE_EMPTY_OBJECTS return(CollectionUtils.IsNullOrEmpty(list) ? null : list); }