public DataClass GetDataClass(Database db, Type type)
        {
            if (cache.ContainsKey(type))
            {
                return(cache[type].CloneT());
            }
            else
            {
                RegisterAssemblyAndCompile(db, type.Assembly, type, false);
                var ch = cache.GetValue(type);

                if (ch == null)
                {
                    RegisterAssemblyAndCompile(db, type.Assembly, type, true);
                    ch = cache.GetValue(type);
                }

                if (ch == null)
                {
                    var table = DataReflectionUtil.GetTableName(type);
                    if (table != null)
                    {
                        throw new Exception("Uncompiled tables: " + table + "\r\nErrors\r\n\r\n: " + string.Join(", ", Database.Errors));
                    }
                    else
                    {
                        throw new Exception("Type not found: " + type.Name);
                    }
                }
                return(ch);
            }
        }
        public string Validate <T>(T record, bool thowException = true)
        {
            // TODO: colocar essa lógica na geração de código pra melhorar a performance
            var b = new StringBuilder();

            if (columns == null)
            {
                columns = DataReflectionUtil.GetMapColumns(typeof(T));
            }

            foreach (var _col in columns)
            {
                string       propertyName = _col.Value.Name;
                var          col          = ColumnInfos[_col.Key];
                string       columnName   = col.ColumnName;
                PropertyInfo prop         = _col.Value;

                var value    = prop.GetValue(record, null);
                var valueStr = value as string;

                if (!col.IsIdentity &&
                    !columnName.EqualsICIC(TableInfo.SequenceColumn) &&
                    value == null && !col.IsNullable)
                {
                    b.AppendFormat($"Property {propertyName} / Column {col.TableName}.{col.ColumnName} does not allow null\r\n");
                }

                if (!string.IsNullOrEmpty(valueStr))
                {
                    if (col.DataType != "CLOB" && col.DataType != "BLOB" && col.DataType != "NCLOB")
                    {
                        if (col.CharacterMaximumLength != 0 &&
                            valueStr.Length > col.CharacterMaximumLength)
                        {
                            b.AppendFormat($"Property {propertyName} / Column {col.TableName}.{col.ColumnName} Exceeded maximum allowed length {col.CharacterMaximumLength}. Field is {valueStr.Length} characters long.\r\n");
                        }
                    }
                }
            }

            if (thowException && !b.IsEmpty())
            {
                throw new Exception(b.ToString());
            }

            return(b.Length == 0 ? null : b.ToString());
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="types"></param>
        /// <param name="db"></param>
        /// <param name="lastModified">Última data de table ou view aterado na base</param>
        /// <returns></returns>
        string GetDirectory(List <Type> types, Database db, string lastModified)
        {
            try
            {
                string nspace = types.First().Namespace;
                var    tnames = new StringBuilder();

                var fullName = this.GetType().Assembly.Location;
                tnames.Append(fullName);
                tnames.Append(getFileTime(fullName));

                foreach (var type in types)
                {
                    tnames.Append(type.FullName + " - " + DataReflectionUtil.GetSchemaName(type) + " - " + DataReflectionUtil.GetTableName(type));
                    var tcols = Cryptography.Hash(string.Join(",", DataReflectionUtil.GetColumns(type).Where(p => p.Value != null).Select(q => q.Value.ToString())));
                    tnames.Append(" -> " + tcols);
                    tnames.AppendLine(Cryptography.Hash(string.Join(",", type.GetProperties().Select(p => p.ToString()))));
                }

                if (!Debugger.IsAttached)
                {
                    tnames.Append(getFileTime(types[0].Assembly.Location));
                }

                string hashName = FileTools.ToValidPath(Cryptography.Hash(
                                                            lastModified + "-"
                                                            + tnames.ToString()
                                                            + db.ProviderType
                                                            + db.Connection.ConnectionString)
                                                        .Replace("=", "").Replace("/", "").Replace("\\", ""));

                string dirBase = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);

                string dir = Path.Combine(dirBase, "Speed", db.ProviderType.ToString(), nspace, hashName);
                return(dir);
            }
            catch (Exception ex)
            {
                Sys.Trace(ex, "Erro em GetDirectory");
                throw;
            }
        }