////TODO this is a temporary solution to avoid automapper ////TODO add some caching public static Tdto Cast <Tdto>(this MySqlDataReader dataReader) { var validTypes = new [] { typeof(string), typeof(int), typeof(int), typeof(bool), typeof(long), typeof(decimal), typeof(float), typeof(int?), typeof(int?), typeof(bool?), typeof(long?), typeof(decimal?), typeof(float?) }; var dtoType = typeof(Tdto); var dtoInstance = Activator.CreateInstance <Tdto>(); if (validTypes.Contains(dtoType)) { dtoInstance = (Tdto)dataReader[0]; return(dtoInstance); } var publicScalarProperties = dtoType.GetProperties().Where(x => validTypes.Contains(x.PropertyType)); var publicScalarFields = dtoType.GetFields().Where(x => validTypes.Contains(x.FieldType)); var missingNames = publicScalarFields .Select(f => f.Name) .Union(publicScalarProperties.Select(p => p.Name)) .Where(n => !dataReader.ContainsOrdinal(n)); if (missingNames.Any()) { var nameList = string.Join(", ", missingNames); throw new InvalidOperationException($"Columns not found in dataReader for DTO {dtoType.Name}: {nameList}"); } foreach (var propertyInfo in publicScalarProperties.Where(p => dataReader.ContainsOrdinal(p.Name))) { var colType = propertyInfo.PropertyType; propertyInfo.SetValue(dtoInstance, dataReader[propertyInfo.Name]); } foreach (var field in publicScalarFields.Where(f => dataReader.ContainsOrdinal(f.Name))) { var colType = field.FieldType; var columIndex = dataReader.GetOrdinal(field.Name); field.SetValue(dtoInstance, dataReader[columIndex]); } return(dtoInstance); }