Пример #1
0
 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));
 }
Пример #2
0
        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);
        }