dimanche 7 novembre 2021

Mapping SQLReader to nested custom classes using reflection

I have the following code which I found on here but I want it to work for classes that have custom type objects inside (class Person having a List of type Fields). What I am doing is, I tried to update the function so that I get all the members of the inner custom classes but I don't know how to combine them back into the original object. Also, if there is a better way to do this, kindly point me in the right direction. The new part is marked as 'starts from here'.

internal static async Task<IEnumerable<T>> ConvertToNestedObjectsAsync<T>(this SqlDataReader rd) where T : class, new()
        {
            Type type = typeof(T);
            var accessor = TypeAccessor.Create(type);
            var members = accessor.GetMembers();
            var tList = new List<T>();

            while (await rd.ReadAsync())
            {
                var t = new T();
                for (int i = 0; i < rd.FieldCount; i++)
                {
                    if (!rd.IsDBNull(i))
                    {
                        string fieldName = rd.GetName(i);

                        if (members.Any(m => string.Equals(m.Name, fieldName, StringComparison.OrdinalIgnoreCase)))
                        {
                            accessor[t, fieldName] = rd.GetValue(i);
                        }
                        else
                        {
                            //starts from here
                            foreach (Member mem in members.Where(mm => !IsPrimitive(mm.Type)).ToList())
                            {
                                var accessorNested = TypeAccessor.Create(mem.Type);
                                var membersNested = accessorNested.GetMembers();
                                if (membersNested.Any(mmm => string.Equals(mmm.Name, fieldName, StringComparison.OrdinalIgnoreCase)))
                                {
                                    accessorNested[mem.Type, fieldName] = rd.GetValue(i);
                                }
                                
                            }


                        }
                    }
                }
                tList.Add(t);
            }

            return tList;
        }

        internal static bool IsPrimitive(Type t)
        {
            return new[]
            {
                typeof(string),
                typeof(char),
                typeof(byte),
                typeof(sbyte),
                typeof(ushort),
                typeof(short),
                typeof(uint),
                typeof(int),
                typeof(ulong),
                typeof(long),
                typeof(float),
                typeof(double),
                typeof(decimal),
                typeof(DateTime),
            }.Contains(t);
        }




Aucun commentaire:

Enregistrer un commentaire