예제 #1
0
        /// <summary>
        /// Add an object to the list. The object is created using values from the list of related
        /// objects passed. This means you dont pass the relation object itself, but rather the
        /// list of objects which are related (in an n:m fashion).
        /// </summary>
        /// <param name="transaction">The transaction within which to execute statements.</param>
        /// <param name="relatedObjects">The list of related objects</param>
        /// <returns>The index of the newly created relation</returns>
        public virtual int Add(Transaction transaction, params object[] relatedObjects)
        {
            Check.VerifyNotNull(relatedObjects, Error.NullParameter, "relatedObjects");
            int expectedArgs = parent == null ? 1 : 0;

            expectedArgs += relatedTypes.Length;
            Check.VerifyEquals(expectedArgs, relatedObjects.Length, Error.DeveloperError,
                               "Invalid use of GentleList (arguments to Add does not match managed type count).");
            Key key = new Key(containedMap.Type, true);

            key = Key.GetKey(broker, key, true, parent);
            // only add first object at this point
            key = Key.GetKey(broker, key, true, relatedObjects[0]);
            // check to see if relation exists based on first object alone
            object relation = relations.Find(key);

            if (relation != null)
            {
                return(relations.IndexOf(relation));
            }
            // make sure the relation is constructed using all objects passed
            for (int i = 1; i < relatedObjects.Length; i++)
            {
                key = Key.GetKey(broker, key, true, relatedObjects[i]);
            }
            relation = containedMap.Construct(key, broker);
            return(relations.Add(transaction, relation));
        }
예제 #2
0
        /// <summary>
        /// Construct an instance of the given type using data from the first row of the
        /// supplied SqlResult instance.
        /// Refer to the Construct method of the <see cref="ObjectMap"/> class for details.
        /// </summary>
        /// <param name="type">The type of object to construct</param>
        /// <param name="sr">The SqlResult instance holding the data</param>
        /// <param name="key">Additional fields not available in the result set (e.g. primary key fields)</param>
        /// <returns>An instance of the given type</returns>
        /// <exception cref="GentleException"> will be raised if no object could be created</exception>
        public static object GetInstance(Type type, SqlResult sr, Key key)
        {
            Check.Verify(sr != null && sr.ErrorCode == 0 && sr.RowsContained == 1,
                         Error.UnexpectedRowCount, sr.RowsContained, 1);
            ObjectMap objectMap = GetMap(sr.SessionBroker, type);

            // check for dynamic type
            if (objectMap.InheritanceMap != null)
            {
                string assemblyQualifiedName = sr.GetString(0, objectMap.InheritanceMap.ColumnName);
                type      = LoadType(assemblyQualifiedName);
                objectMap = GetMap(sr.SessionBroker, type);                   // update objectmap to actual type from database
            }
            // determine constructor
            object[] row = (object[])sr.Rows[0];
            int      columnComboHashCode = objectMap.DetermineConstructor(sr.ColumnNames, row);
            // create object
            object result = objectMap.Construct(columnComboHashCode, row, sr.SessionBroker);

            // check whether to store query result information
            if (GentleSettings.CacheObjects && GentleSettings.SkipQueryExecution &&
                objectMap.CacheStrategy != CacheStrategy.Never)
            {
                IList <string> results = new List <string> {
                    objectMap.GetInstanceHashKey(result)
                };
                CacheManager.Insert(sr.Statement.CacheKey, results);
            }
            // mark as persisted
            if (result is IEntity)
            {
                (result as IEntity).IsPersisted = true;
            }
            return(result);
        }
예제 #3
0
        /// <summary>
        /// Construct multiple objects of a given type from the data contained in the given SqlResult
        /// object. Refer to the Construct method of the <see cref="ObjectMap"/> class for details.
        /// </summary>
        /// <param name="type">The type of object to construct</param>
        /// <param name="sr">The SqlResult instance holding the data</param>
        /// <param name="result">An optional existing container in which to store the created objects. If
        /// this parameter is null a new IList instance will be created.</param>
        /// <returns>An IList holding the created objects</returns>
        /// <exception cref="GentleException"> will be raised if no object could be created</exception>
        public static IList GetCollection(Type type, SqlResult sr, IList result)
        {
            if (result == null)
            {
                result = MakeGenericList(type);
            }
            ObjectMap objectMap = GetMap(sr.SessionBroker, type);
            // check whether to store query result information
            bool isCache = GentleSettings.CacheObjects && GentleSettings.SkipQueryExecution &&
                           objectMap.CacheStrategy != CacheStrategy.Never;
            IList cache = isCache ? new ArrayList() : null;

            // remember keys of cached objects to permit SQE
            // process result set
            if (sr.RowsContained > 0)
            {
                ObjectMap actualMap           = objectMap;
                int       columnComboHashCode = 0;
                // cache constructor info for dynamic type construction
                Hashtable typeHash = null;
                Hashtable typeMaps = null;
                if (objectMap.InheritanceMap != null)
                {
                    typeHash = new Hashtable();
                    typeMaps = new Hashtable();
                }
                else                 // precompute fixed hash
                {
                    columnComboHashCode = objectMap.DetermineConstructor(sr.ColumnNames, (object[])sr.Rows[0]);
                }
                // process result set
                for (int i = 0; i < sr.Rows.Count; i++)
                {
                    object[] row = (object[])sr.Rows[i];
                    // dynamic object construction handling
                    if (typeHash != null)
                    {
                        string assemblyQualifiedName = sr.GetString(i, objectMap.InheritanceMap.ColumnName);
                        if (typeHash.ContainsKey(assemblyQualifiedName))
                        {
                            columnComboHashCode = (int)typeHash[assemblyQualifiedName];
                            actualMap           = (ObjectMap)typeMaps[assemblyQualifiedName];
                        }
                        else
                        {
                            Type rowType = LoadType(assemblyQualifiedName);
                            actualMap                       = GetMap(sr.SessionBroker, rowType);
                            columnComboHashCode             = actualMap.DetermineConstructor(sr.ColumnNames, (object[])sr.Rows[0]);
                            typeMaps[assemblyQualifiedName] = actualMap;
                            typeHash[assemblyQualifiedName] = columnComboHashCode;
                        }
                    }
                    // skip non-derived classes for dynamic types
                    if (actualMap.Type == objectMap.Type || actualMap.Type.IsSubclassOf(objectMap.Type))
                    {
                        object obj = actualMap.Construct(columnComboHashCode, row, sr.SessionBroker);
                        if (obj is IEntity)
                        {
                            (obj as IEntity).IsPersisted = true;
                        }
                        result.Add(obj);
                        // cache result if necessary
                        if (isCache)
                        {
                            cache.Add(actualMap.GetInstanceHashKey(obj));
                        }
                    }
                }
            }
            if (isCache)
            {
                CacheManager.Insert(sr.Statement.CacheKey, cache);
            }
            return(result);
        }