public static ReadInfoByType <T> CreateByType <T>(IDataReader reader, ReadOptions readOptions) where T : new() { ReadOptions readOpt = GetReadOptions(readOptions); ReaderField[] readerFields = new ReaderField[reader.FieldCount]; for (int i = 0; i < reader.FieldCount; i++) { readerFields[i] = new ReaderField() { Ordinal = i, Name = reader.GetName(i) }; } Type type = typeof(T); FieldInfo[] fiAll = new FieldInfo[0]; if ((readOpt.FromTypeOption.Value & FromTypeOption.PublicField) == FromTypeOption.PublicField) { fiAll = type.GetFields(BindingFlags.Instance | BindingFlags.Public); if ((readOpt.FromTypeOption.Value & FromTypeOption.Collection) == 0) { fiAll = fiAll.Where(x => !Helpers.IsCollection(x.FieldType)).ToArray(); } } PropertyInfo[] piAll = new PropertyInfo[0]; if ((readOpt.FromTypeOption.Value & FromTypeOption.PublicProperty) == FromTypeOption.PublicProperty) { piAll = type.GetProperties(BindingFlags.Instance | BindingFlags.Public); if ((readOpt.FromTypeOption.Value & FromTypeOption.Collection) == 0) { piAll = piAll.Where(x => !Helpers.IsCollection(x.PropertyType)).ToArray(); } } if (readOpt.CaseSensitiveFieldsMatching.Value) { if (readerFields.GroupBy(x => x.Name).Any(x => x.Count() > 1)) { throw new ArgumentException("Reader field names has been duplicated"); } if (piAll.Select(x => x.Name).Concat(fiAll.Select(x => x.Name)).GroupBy(x => x).Any(x => x.Count() > 1)) { throw new ArgumentException("Destination object field names has been duplicated"); } } else { if (readerFields.GroupBy(x => x.Name.ToLowerInvariant()).Any(x => x.Count() > 1)) { throw new ArgumentException("Reader field names has been duplicated"); } if (piAll.Select(x => x.Name.ToLowerInvariant()).Concat(fiAll.Select(x => x.Name.ToLowerInvariant())) .GroupBy(x => x).Any(x => x.Count() > 1)) { throw new ArgumentException("Destination object field names has been duplicated"); } } var fiCommon = readOpt.CaseSensitiveFieldsMatching.Value ? fiAll.Join(readerFields, x => x.Name, x => x.Name, (x, y) => new { FieldInfo = x, ReaderField = y }).ToArray() : fiAll.Join(readerFields, x => x.Name.ToLowerInvariant(), x => x.Name.ToLowerInvariant(), (x, y) => new { FieldInfo = x, ReaderField = y }).ToArray(); var piCommon = readOpt.CaseSensitiveFieldsMatching.Value ? piAll.Join(readerFields, x => x.Name, x => x.Name, (x, y) => new { PropertyInfo = x, ReaderField = y }).ToArray() : piAll.Join(readerFields, x => x.Name.ToLowerInvariant(), x => x.Name.ToLowerInvariant(), (x, y) => new { PropertyInfo = x, ReaderField = y }).ToArray(); Helpers.CheckFieldSelection(readOpt.FieldsSelector.Value, readerFields.Length, fiAll.Length + piAll.Length, fiCommon.Length + piCommon.Length); Type nullableTypeDef = typeof(Nullable <int>).GetGenericTypeDefinition(); FieldInfo[] fi = new FieldInfo[fiCommon.Length]; int[] fiInd = new int[fiCommon.Length]; bool[] fiNullable = new bool[fiCommon.Length]; for (int i = 0; i < fiCommon.Length; i++) { fi[i] = fiCommon[i].FieldInfo; fiInd[i] = fiCommon[i].ReaderField.Ordinal; fiNullable[i] = !fiCommon[i].FieldInfo.FieldType.GetTypeInfo().IsValueType || (fiCommon[i].FieldInfo.FieldType.GetTypeInfo().IsGenericType&& fiCommon[i].FieldInfo.FieldType.GetGenericTypeDefinition().Equals(nullableTypeDef)); } PropertyInfo[] pi = new PropertyInfo[piCommon.Length]; int[] piInd = new int[piCommon.Length]; bool[] piNullable = new bool[piCommon.Length]; for (int i = 0; i < piCommon.Length; i++) { pi[i] = piCommon[i].PropertyInfo; piInd[i] = piCommon[i].ReaderField.Ordinal; piNullable[i] = !piCommon[i].PropertyInfo.PropertyType.GetTypeInfo().IsValueType || (piCommon[i].PropertyInfo.PropertyType.GetTypeInfo().IsGenericType&& piCommon[i].PropertyInfo.PropertyType.GetGenericTypeDefinition().Equals(nullableTypeDef)); } return(new ReadInfoByType <T>() { Reader = reader, fi = fi, fiInd = fiInd, fiNullable = fiNullable, pi = pi, piInd = piInd, piNullable = piNullable }); }
public static ReadInfoAnonymous <T> CreateAnonymous <T>(IDataReader reader, T proto, ReadOptions readOptions) { ReadOptions readOpt = GetReadOptions(readOptions); ReaderField[] readerFields = new ReaderField[reader.FieldCount]; for (int i = 0; i < reader.FieldCount; i++) { readerFields[i] = new ReaderField() { Ordinal = i, Name = reader.GetName(i) }; } ConstructorInfo constructor = typeof(T).GetConstructors().First(); ParameterInfo[] piAll = constructor.GetParameters(); if (readOpt.CaseSensitiveFieldsMatching.Value) { if (readerFields.GroupBy(x => x.Name).Any(x => x.Count() > 1)) { throw new ArgumentException("Reader field names has been duplicated"); } if (piAll.GroupBy(x => x.Name).Any(x => x.Count() > 1)) { throw new ArgumentException("Destination object field names has been duplicated"); } } else { if (readerFields.GroupBy(x => x.Name.ToLowerInvariant()).Any(x => x.Count() > 1)) { throw new ArgumentException("Reader field names has been duplicated"); } if (piAll.GroupBy(x => x.Name.ToLowerInvariant()).Any(x => x.Count() > 1)) { throw new ArgumentException("Destination object field names has been duplicated"); } } var piCommon = readOpt.CaseSensitiveFieldsMatching.Value ? piAll.Join(readerFields, x => x.Name, x => x.Name, (x, y) => new { ParameterInfo = x, ReaderField = y }).ToArray() : piAll.Join(readerFields, x => x.Name.ToLowerInvariant(), x => x.Name.ToLowerInvariant(), (x, y) => new { ParameterInfo = x, ReaderField = y }).ToArray(); Helpers.CheckFieldSelection(readOpt.FieldsSelector.Value, readerFields.Length, piAll.Length, piCommon.Length); Type nullableTypeDef = typeof(Nullable <int>).GetGenericTypeDefinition(); ParameterInfo[] pi = new ParameterInfo[piCommon.Length]; int[] piInd = new int[piCommon.Length]; bool[] piNullable = new bool[piCommon.Length]; for (int i = 0; i < piCommon.Length; i++) { pi[i] = piCommon[i].ParameterInfo; piInd[i] = piCommon[i].ReaderField.Ordinal; piNullable[i] = !piCommon[i].ParameterInfo.ParameterType.GetTypeInfo().IsValueType || (piCommon[i].ParameterInfo.ParameterType.GetTypeInfo().IsGenericType&& piCommon[i].ParameterInfo.ParameterType.GetGenericTypeDefinition().Equals(nullableTypeDef)); } return(new ReadInfoAnonymous <T>() { Reader = reader, constructor = constructor, piAll = piAll, pi = pi, piInd = piInd, piNullable = piNullable }); }