////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);
        }