/// <summary>
        /// Gets the configuration of all tables.
        /// </summary>
        /// <returns>The configuration of all tables.</returns>
        public virtual IList <ITableInfo> GetConfig()
        {
            if (Tables.Count > 0)
            {
                return(Tables);
            }

            ResultData resultData = new ResultData(ConfigData.ConfigTypes.Select(x => x.Value.Type).ToArray());

            foreach (IConfigProcessor processor in Processors)
            {
                if ((!ConfigData.EnableAttributes && processor is IAttributeProcessor) ||
                    (!ConfigData.EnableMetadata && processor is IMetadataProcessor))
                {
                    continue;
                }

                processor.Process(ConfigData, resultData);
            }

            foreach (TableInfo tableInfo in resultData.ResultTypes.Select(x => x.Value)
                     .Where(x => ConfigData.GetConfig(x.Type).IsTable == true))
            {
                // Register in ExpressionProcessor
                ExpressionProcessor.AddTable(tableInfo.Type);

                // Add table and make readonly
                Tables.Add(ToReadOnly(tableInfo));
            }

            ConfigData = null;
            return(Tables);
        }
示例#2
0
        public void Remove_Table()
        {
            ExpressionProcessor.AddTable(typeof(CustomTable));
            ExpressionProcessor.RemoveTable(typeof(CustomTable));

            Assert.False(ExpressionProcessor.ContainsTable(typeof(CustomTable)));
        }
示例#3
0
        public void Add_Table()
        {
            ExpressionProcessor.AddTable(typeof(CustomTable));

            Assert.True(ExpressionProcessor.ContainsTable(typeof(CustomTable)));
        }
示例#4
0
        /// <summary>
        /// Gets the config of all tables.
        /// </summary>
        /// <returns>The config of all tables.</returns>
        public IList <TableInfo> GetConfig()
        {
            if (Tables.Count > 0)
            {
                return(Tables);
            }

            IDictionary <string, TableInfo> tables = new Dictionary <string, TableInfo>();
            var levels = GetLevels();

            foreach (var level in levels)
            {
                foreach (ConfigData config in level)
                {
                    // Get parent config
                    TableInfo parentInfo = null;
                    Type      parentType = config.Type.BaseType;
                    if (parentType != null && parentType != typeof(object))
                    {
                        tables.TryGetValue(parentType.FullName, out parentInfo);
                    }

                    TableInfo tableInfo = new TableInfo();
                    tableInfo.Type = config.Type;

                    // Get IsTable
                    TableAttribute tableAttr = config.Type.GetCustomAttribute <TableAttribute>();
                    if (!config.IsTable.HasValue)
                    {
                        if (tableAttr != null)
                        {
                            config.IsTable = tableAttr.IsTable;
                        }
                        else
                        {
                            config.IsTable = !config.Type.IsAbstract;
                        }
                    }

                    // Get InheritTable
                    if (!config.InheritTable.HasValue && tableAttr != null)
                    {
                        config.InheritTable = tableAttr.InheritTable;
                    }

                    // Get InheritColumns
                    if (config.InheritTable == true)
                    {
                        config.InheritColumns = true;
                    }
                    else if (!config.InheritColumns.HasValue)
                    {
                        if (tableAttr != null && tableAttr.InheritColumnsHasValue)
                        {
                            config.InheritColumns = tableAttr.InheritColumns;
                        }
                        else
                        {
                            config.InheritColumns = config.Type.BaseType.IsAbstract == true;
                        }
                    }

                    if ((config.InheritTable == true || config.InheritColumns == true) && parentInfo == null)
                    {
                        throw new InvalidConfigurationException(
                                  $"The type \"{config.Type}\" does not have a base type to inherit");
                    }

                    // Get table name
                    if (config.InheritTable == true)
                    {
                        tableInfo.TableName = parentInfo.TableName;
                    }
                    else
                    {
                        if (string.IsNullOrEmpty(config.TableName))
                        {
                            tableInfo.TableName = tableAttr?.Name ?? TableNameDefault(config.Type);
                        }
                        else
                        {
                            tableInfo.TableName = config.TableName;
                        }
                    }

                    // Get primary keys
                    List <string> primaryKeys = new List <string>();
                    if (config.PrimaryKeys.Count == 0)
                    {
                        config.PrimaryKeys.AddRange(config.Properties.ToDictionary(x => x,
                                                                                   x => x.GetCustomAttribute <PrimaryKeyAttribute>())
                                                    .Where(x => x.Value != null).OrderBy(x => x.Value.Order).Select(x => x.Key.Name));
                    }

                    if (config.PrimaryKeys.Count > 0)
                    {
                        tableInfo.PrimaryKeys = config.PrimaryKeys.ToArray();
                    }
                    else if (parentInfo?.PrimaryKeys != null)
                    {
                        tableInfo.PrimaryKeys = parentInfo.PrimaryKeys;
                    }
                    else
                    {
                        string key = PrimaryKeyDefault(config.Type);
                        if (key != null)
                        {
                            if (config.Type.GetProperty(key) == null)
                            {
                                throw new InvalidConfigurationException($"Type \"{config.Type}\" does not have "
                                                                        + $"property \"{key}\".");
                            }
                            tableInfo.PrimaryKeys = new string[] { key };
                        }
                        else
                        {
                            tableInfo.PrimaryKeys = Array.Empty <string>();
                        }
                    }

                    // Get ignore
                    config.Ignore.AddRange(config.Properties.Where(x => x.GetCustomAttribute <IgnoreAttribute>() != null)
                                           .Select(x => x.Name));
                    config.Ignore = config.Ignore.Distinct().ToList();

                    tables.Add(tableInfo.Type.FullName, tableInfo);
                }
            }

            foreach (var level in levels)
            {
                foreach (ConfigData config in level)
                {
                    // Get parent config
                    TableInfo parentInfo = null;
                    Type      parentType = config.Type.BaseType;
                    if (parentType != null && parentType != typeof(object))
                    {
                        tables.TryGetValue(parentType.FullName, out parentInfo);
                    }

                    TableInfo tableInfo = tables[config.Type.FullName];
                    tableInfo.Type = config.Type;

                    // Get columns
                    foreach (PropertyInfo property in config.Properties)
                    {
                        if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType) &&
                            property.PropertyType != typeof(string))
                        {
                            continue;
                        }
                        else if (config.ForeignKeys.ContainsKey(property.Name))
                        {
                            foreach (var key in config.ForeignKeys[property.Name])
                            {
                                config.Columns.Add(key.PropertyName);
                                config.ColumnsNames.Add(key.PropertyName, key.ColumnName);
                            }
                        }
                        else if (!Config.ContainsKey(property.PropertyType.FullName))
                        {
                            config.Columns.Add(property.Name);

                            if (!config.ColumnsNames.ContainsKey(property.Name))
                            {
                                ForeignKeyAttribute[] keys = property.GetCustomAttributes <ForeignKeyAttribute>().ToArray();
                                if (keys.Length > 1)
                                {
                                    throw new InvalidConfigurationException($"Invalid multiple foreign key "
                                                                            + $"for property \"{property.Name}\" in type \"{config.Type}\".");
                                }
                                else if (keys.Length == 1 && !string.IsNullOrEmpty(keys[0].Name))
                                {
                                    config.ColumnsNames.Add(property.Name, keys[0].Name);
                                }
                                else
                                {
                                    ColumnAttribute column = property.GetCustomAttribute <ColumnAttribute>();

                                    config.ColumnsNames.Add(property.Name, !string.IsNullOrEmpty(column?.Name)
                                        ? column.Name : property.Name);
                                }
                            }
                        }
                        else
                        {
                            ForeignKeyAttribute[] keys = property.GetCustomAttributes <ForeignKeyAttribute>().ToArray();

                            if (keys.Length == 0)
                            {
                                TableInfo tableInfoFK = tables[property.PropertyType.FullName];

                                foreach (string keyFk in tableInfoFK.PrimaryKeys)
                                {
                                    string column = property.Name + "." + keyFk;
                                    config.Columns.Add(column);
                                    config.ColumnsNames.Add(column, property.Name + keyFk);
                                }
                            }
                            else if (keys.Length == 1)
                            {
                                TableInfo tableInfoFK = tables[property.PropertyType.FullName];

                                string keyFk = keys[0].PropertyName;
                                if (!string.IsNullOrEmpty(keyFk))
                                {
                                    string column = property.Name + "." + keyFk;
                                    config.Columns.Add(column);
                                    config.ColumnsNames.Add(column, keys[0].Name);
                                }
                                else if (tableInfoFK.PrimaryKeys.Length > 1)
                                {
                                    throw new InvalidConfigurationException($"Foreign key propertyName not specified "
                                                                            + $"for property \"{property.Name}\" in type \"{config.Type}\" and the "
                                                                            + $"type {property.PropertyType} have multiple primary keys.");
                                }
                                else if (tableInfoFK.PrimaryKeys.Length == 0)
                                {
                                    throw new InvalidConfigurationException($"Foreign key propertyName not specified "
                                                                            + $"for property \"{property.Name}\" in type \"{config.Type}\" and the "
                                                                            + $"type {property.PropertyType} does not have primary key.");
                                }
                                else
                                {
                                    string column = property.Name + "." + tableInfoFK.PrimaryKeys[0];
                                    config.Columns.Add(column);
                                    config.ColumnsNames.Add(column, keys[0].Name);
                                }
                            }
                            else
                            {
                                if (keys.Any(x => string.IsNullOrEmpty(x.PropertyName)))
                                {
                                    throw new InvalidConfigurationException($"Foreign key propertyName not specified "
                                                                            + $"for property \"{property.Name}\" in type \"{config.Type}\".");
                                }

                                foreach (var key in keys)
                                {
                                    string column = property.Name + "." + key.PropertyName;
                                    config.Columns.Add(column);
                                    config.ColumnsNames.Add(column, !string.IsNullOrEmpty(key.Name) ? key.Name
                                        : property.Name + key.PropertyName);
                                }
                            }
                        }
                    }

                    List <string> columns = new List <string>();
                    if (config.InheritColumns == true)
                    {
                        columns.AddRange(parentInfo.Columns);
                    }
                    columns.AddRange(config.Columns);

                    tableInfo.Columns = tableInfo.PrimaryKeys.Union(columns).Distinct()
                                        .Where(x => !config.Ignore.Contains(x)).ToArray();

                    // Get column names
                    IDictionary <string, string> columnsNames = new Dictionary <string, string>();
                    if (parentInfo != null)
                    {
                        foreach (var item in parentInfo.ColumnNamesDic.Where(x => tableInfo.Columns.Contains(x.Key)))
                        {
                            columnsNames[item.Key] = item.Value;
                        }
                    }

                    foreach (var item in config.ColumnsNames.Where(x => tableInfo.Columns.Contains(x.Key)))
                    {
                        columnsNames[item.Key] = item.Value;
                    }

                    tableInfo.ColumnNamesDic = columnsNames;
                    tableInfo.ColumnNames    = tableInfo.Columns.Select(x => tableInfo.ColumnNamesDic[x])
                                               .Distinct().ToArray();
                }
            }

            foreach (TableInfo tableInfo in tables.Where(x => Config[x.Key].IsTable == true).Select(x => x.Value))
            {
                Tables.Add(tableInfo);
                // Register in ExpressionProcessor
                ExpressionProcessor.AddTable(tableInfo.Type);
            }

            return(Tables);
        }