Пример #1
0
        /// <summary>
        /// Adds every publicly-settable field or property of the root entity to the select list, removing any beginning underscore from the name of the selected column.
        /// </summary>
        /// <returns>
        /// This RootQueryBuilder object.
        /// </returns>
        public RootQueryBuilder <T> Select(IEnumerable <Expression <Func <T, object> > > getterExprs)
        {
            // 1. Cache all setters for type T.
            IDictionary <string, SetValue> setters = CachedTypeData.FetchSettersOf <T>();

            // 2. Add "RootTable"."propOrFieldName" to the select list or just "propOrFieldName" if table_alias is null for every
            //    field and property returned in getterExprs
            foreach (Expression <Func <T, object> > getterExpr in getterExprs)
            {
                string propOrFieldName = ExpressionTreeHelper.GetPropOrFieldNameFromLambdaExpr <T>(getterExpr);

                // Only if there is a public setter for this property or if the field is public
                if (setters.ContainsKey(propOrFieldName) == false)
                {
                    continue;
                }

                // Remove a possible underscore before adding it to selection
                if (propOrFieldName[0] == '_')
                {
                    propOrFieldName = propOrFieldName.Substring(1);
                }

                string select_projection = RootTable + "." + propOrFieldName;
                Qb.Select(select_projection);
            }

            return(this);
        }
Пример #2
0
        /// <summary>
        /// Adds every publicly-settable field or property in type <typeref name="T"/> to the select list, removing any leading underscore from the name of the selected column.
        /// </summary>
        /// <returns>
        /// This RootQueryBuilder object.
        /// </returns>
        public RootQueryBuilder <T> SelectAllColumns()
        {
            // 1. Go after all the public settable properties and public fields in type T
            IDictionary <string, SetValue> setters = CachedTypeData.FetchSettersOf <T>();

            // 2. Add all of them to the select list!
            foreach (string propOrField in setters.Select(x => x.Key))
            {
                string selectableName = propOrField;
                if (selectableName[0] == '_')
                {
                    selectableName = propOrField.Substring(1);
                }

                // Just to have pretty SQL when there is only one table queried
                if (QueriedTables.Count == 1)
                {
                    Qb.Select(selectableName);
                }
                else
                {
                    Qb.Select(RootTable + "." + selectableName);
                }
            }

            return(this);
        }
Пример #3
0
        /// <summary>
        /// Execute the query and enumerates the results of type <typeparamref name="T"/>. This method DOES NOT avoid duplicates
        /// of the root entity from being returned if there is any join to a one-to-many relationed entity. Do not make this public,
        /// since enumerating results one by one will interfere with one-to-many fetching (by not having all elements of the collection
        /// for some yielded results).
        /// </summary>
        /// <param name='com'>
        /// The IDbCommand to be executed.
        /// </param>
        /// <typeparam name='T'>
        /// The type of each result.
        /// </typeparam>
        private IEnumerable <T> AsEnumerable(IDbCommand com)
        {
            // Get the fields and properties of type T and put their setter and getter methods in the cache, if not already there
            IDictionary <string, SetValue> rootEntitySetters = CachedTypeData.FetchSettersOf <T>();

            // To update collections of all returned root entities in one-to-many relations, we keep them here for easy access
            IDictionary <T, IDictionary <string, IList> > rootEntitiesAndAssociatedCollections = null;
            bool hasSomeFetchManyAssociation = FetchManyFetchers != null;

            if (hasSomeFetchManyAssociation)
            {
                rootEntitiesAndAssociatedCollections = new Dictionary <T, IDictionary <string, IList> >();
            }

            using (IDataReader dr = com.ExecuteReader())
            {
                while (dr.Read())
                {
                    T temp = new T();

                    // Set the fields/properties of the root object accordingly, skipping collections at first
                    MemberSetter.SetNonCollectionMembersOf(temp, RootEntityProjectionsMap, dr);

                    if (hasSomeFetchManyAssociation)
                    {
                        if (rootEntitiesAndAssociatedCollections.ContainsKey(temp) == false)
                        {
                            rootEntitiesAndAssociatedCollections.Add(temp, new Dictionary <string, IList>());
                        }

                        foreach (var collectionMemberFetcher in FetchManyFetchers)
                        {
                            string   memberName = collectionMemberFetcher.Key;
                            SetValue setter     = rootEntitySetters[memberName];
                            ICollectionResultsFetcher <T> collectionFetcher        = collectionMemberFetcher.Value;
                            IDictionary <string, IList>   collectionsPerMemberName = rootEntitiesAndAssociatedCollections[temp];

                            IList collection;
                            if (collectionsPerMemberName.ContainsKey(memberName))
                            {
                                collection = collectionsPerMemberName[memberName];
                                setter(temp, collection);
                            }
                            else
                            {
                                collectionFetcher.CreateCollectionAndAssignToMember(temp, setter, out collection);
                                collectionsPerMemberName.Add(memberName, collection);
                            }

                            // Now add an element to the collection and set its properties
                            collectionFetcher.AddElementToCollection(dr, collection);
                        }
                    }

                    yield return(temp);
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Adds every publicly-settable field or property in type <typeref name="T"/> to the select list, removing any leading underscore from the name of the selected column.
        /// </summary>
        /// <returns>
        /// This QueryBuilder object.
        /// </returns>
        /// <typeparam name='T'>
        /// The class with the properties to be selected.
        /// </typeparam>
        public QueryBuilder AddColumnsOf <T>()
        {
            // 1. Go after all the public settable properties and public fields in type T
            IDictionary <string, SetValue> setters = CachedTypeData.FetchSettersOf <T>();

            // 2. Add all of them to the select list!
            foreach (string propOrField in setters.Select(x => x.Key))
            {
                string selectableName = propOrField;
                if (selectableName[0] == '_')
                {
                    selectableName = propOrField.Substring(1);
                }

                Select(selectableName);
            }

            return(this);
        }
Пример #5
0
        /// <summary>
        /// Goes through the list of projections in the SELECT clause and removes the projections whose
        /// names are not similar to any of the names of T's public fields and properties.
        /// It also aliases similar names correctly, putting an underscore if the property/field starts with an underscore.
        /// </summary>
        /// <typeparam name='T'>
        /// The type whose properties are to be aliased and fetched.
        /// </typeparam>
        public QueryBuilder RemoveSelectionsNotOf <T>()
        {
            IDictionary <string, SetValue> setters = CachedTypeData.FetchSettersOf <T>();

            IList <ProjectionFragment> newSelects = new List <ProjectionFragment>();

            foreach (ProjectionFragment proj in selectedProjections)
            {
                string fqn = proj.GetName();

                // If the projection's name is not a property name, then..
                if (!setters.ContainsKey(fqn))
                {
                    // 1. The property might begin with an underscore, check for that and alias the projection correctly
                    if (setters.ContainsKey("_" + fqn))
                    {
                        proj.As("_" + fqn);

                        newSelects.Add(proj);
                        //Console.WriteLine("- Found {0}", proj.GetName());
                    }

                    // 2. The property does not begin with an underscore, don't add it to the new list (do nothing)
                    else
                    {
                        //Console.WriteLine("- Couldn't find a property or field named {0} or _{0} with a public setter", fqn);
                    }
                }

                // If it is a property name, it must be included in the new select list!
                else
                {
                    newSelects.Add(proj);
                    //Console.WriteLine("Found {0}", proj.GetName());
                }
            }

            // Renews the select list
            selectedProjections = newSelects;

            return(this);
        }
Пример #6
0
        /// <summary>
        /// Sets the non collection members of <paramref name="obj"/> as long as they are present in <paramref name="columnsNames"/>.
        /// </summary>
        /// <param name="obj">The object whose fields and properties will be set.</param>
        /// <param name="initialColumnIdx">The zero-starting index of the first column in <paramref name="columnsNames"/>.</param>
        /// <param name="columnsNames">A mapping of the queried projections to <paramref name="obj"/>'s members' names.</param>
        /// <param name="dr">The IDataReader from which columns' values will be retrieved.</param>
        public static void SetNonCollectionMembersOf <T>(T obj, IDictionary <string, string> columnsNames, IDataReader dr)
        {
            var setters = CachedTypeData.FetchSettersOf <T>();

            foreach (KeyValuePair <string, string> projectionAndMember in columnsNames)
            {
                string   memberName     = projectionAndMember.Value;
                string   projectionName = projectionAndMember.Key;
                SetValue setter;
                try
                {
                    setter = setters[memberName];
                }
                catch (KeyNotFoundException)
                {
                    // Just skip for now.. Assume this column is not in this object but may be in another
                    continue;
                    //throw new InvalidOperationException("Object of class " + typeof(T2) + " does not possess a publicly settable member named \"" + memberName + "\"");
                }

                // Special case of collection. Skip!
                MemberInfo memberInfo = CachedTypeData.GetMemberInfo <T>(memberName);
                if (TypeUtils.IsGenericList(memberInfo.GetUnderlyingType()))
                {
                    continue;
                }

                // Check for nulls
                int columnIdx = dr.GetOrdinal(projectionName);

                if (dr.IsDBNull(columnIdx))
                {
                    setter(obj, null);
                }
                else
                {
                    setter(obj, dr.GetValue(columnIdx));
                }
            }
        }