/// <summary>
        /// Used for internal testing.
        /// </summary>
        /// <param name="type">The parameter is not used.</param>
        /// <param name="name">The parameter is not used.</param>
        /// <param name="parentType">The parameter is not used.</param>
        /// <returns>The parameter is not used.</returns>
        public static IList <string> FindParentIDAccessor(Type type, string name, Type parentType)
        {
            var accessor = ChildMapperHelper.FindParentIDAccessor(type, name, parentType);

            if (accessor == null)
            {
                return(new List <string>());
            }
            else
            {
                return(accessor.MemberNames.ToList());
            }
        }
        /// <summary>
        /// Creates a child record reader that autogroups the given type, based on the parent's ids.
        /// </summary>
        /// <typeparam name="TId">The type of the ID.</typeparam>
        /// <param name="parentType">The type of the parent.</param>
        /// <returns>A child record reader.</returns>
        private IChildRecordReader <T, TId> CreateAutoGroupBy <TId>(Type parentType)
        {
            // if we can detect the parent ids from the child class, then use that to do the mapping
            var idAccessor = ChildMapperHelper.FindParentIDAccessor(typeof(T), null, parentType);

            if (idAccessor != null)
            {
                var getid = idAccessor.CreateGetMethod <T, TId>();
                return(new ChildRecordReader <T, TId, T>(this, records => records.GroupBy(getid, r => r)));
            }
            else
            {
                List <Type> guardianTypes = new List <Type>();

                // if a selector was specified, use it, else use the parent's ID accessor to define external columns to use as the key
                if (typeof(TId) != typeof(object))
                {
                    if (typeof(TId).Name.StartsWith("Tuple`", StringComparison.OrdinalIgnoreCase))
                    {
                        guardianTypes.AddRange(typeof(TId).GetGenericArguments());
                    }
                    else
                    {
                        guardianTypes.Add(typeof(TId));
                    }
                }
                else
                {
                    guardianTypes.AddRange(ChildMapperHelper.GetIDAccessor(parentType).MemberTypes);
                }

                guardianTypes.Insert(0, typeof(T));
                var guardianType = GetGuardianType(guardianTypes.Count).MakeGenericType(guardianTypes.ToArray());

#if NET35
                var getReader = this.GetType().GetMethod("GetAdaptedReader", BindingFlags.Instance | BindingFlags.NonPublic).MakeGenericMethod(guardianType, typeof(Guardian <T>));
#else
                var getReader = this.GetType().GetMethod("GetGuardianReader").MakeGenericMethod(guardianType);
#endif

                var reader = (IRecordReader <Guardian <T> >)getReader.Invoke(this, Parameters.EmptyArray);

                return(new ChildRecordReader <Guardian <T>, TId, T>(reader, records => records.GroupBy(g => (TId)g.GetID(), g => g.Object)));
            }
        }
Example #3
0
 /// <summary>
 /// Gets the ID selector from the class, looking for ID, classID, and then anything with xxxID.
 /// </summary>
 /// <returns>An accessor for the ID field.</returns>
 private static Func <T, Object> GetParentIDSelector()
 {
     return(ChildMapperHelper.FindParentIDAccessor(typeof(T), null, typeof(T)).CreateGetMethod <T, Object>());
 }