Пример #1
0
        /// <summary>
        /// Load meta data from dotwebdb.
        /// </summary>
        /// <param name="sharedContext">Indicates that dbContext used in the process is the shared one.</param>
        public void LoadFromConfig(bool sharedContext = false)
        {
            if (string.IsNullOrEmpty(ConfigurationManager.AppSettings["appId"]))
            {
                throw new ArgumentException("appId must be specified in config.");
            }
            appId = int.Parse(ConfigurationManager.AppSettings["appId"].ToString());
            if (sharedContext && dbConfig == null)
            {
                throw new ArgumentException("using shared context requires initialization.");
            }

            var context = dbConfig;

            if (!sharedContext)
            {
                context = new DotWebDb();
            }

            schemaInfo.App = context.Apps
                             .Include(a => a.Groups)
                             .Include(a => a.Groups.Select(g => g.Modules))
                             .SingleOrDefault(a => a.Id == appId);

            schemaInfo.Tables = context.Tables
                                .Include(t => t.Columns)
                                .Include(t => t.Children)
                                .Include(t => t.App)
                                .Where(t => t.AppId == appId).ToList();

            if (!sharedContext)
            {
                context.Dispose();
            }
        }
Пример #2
0
        /// <summary>
        /// Ensure that appId key presents in the configuration file. Every web application must has corresponding appId.
        /// </summary>
        /// <param name="context">An instance of <see cref="DotWebDb"/>.</param>
        private void EnsureApp(DotWebDb context)
        {
            if (string.IsNullOrEmpty(ConfigurationManager.AppSettings["appId"]))
            {
                throw new ArgumentException("appId must be specified in config.");
            }
            appId = int.Parse(ConfigurationManager.AppSettings["appId"].ToString());
            var app = context.Apps.SingleOrDefault(a => a.Id == appId);

            if (app == null)
            {
                app = new App();
                // App is initiated with a default value
                var appName = "Sample App " + DateTime.Today.ToShortDateString();
                if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["appName"]))
                {
                    // If appName presents in configuration file, use it
                    appName = ConfigurationManager.AppSettings["appName"];
                }

                app.Id          = appId;
                app.Name        = appName;
                app.Description = "This app was automatically generated from DbInspector, please change the name and description appropriately.";
                context.Apps.Add(app);
                context.SaveChanges();
            }
            schemaInfo.App = app;
        }
Пример #3
0
        /// <summary>
        /// Look up display column can be determined manually in DotWeb admin interface. But, upon auto-generation
        /// it will be deducted from column which name is Name or Title. It thera are no such column names, the
        /// the first column will be used instead.
        /// </summary>
        /// <param name="context"></param>
        private void DetermineColumnForLookUpDisplay(DotWebDb context)
        {
            var tables = context.Tables.Include(t => t.Columns).Where(t => t.AppId == appId && t.LookUpDisplayColumnId == null);

            foreach (var table in tables)
            {
                // Determines lookup display column
                var lookUpColumns = table.Columns.Where(c => c.Name.Equals("Name", StringComparison.InvariantCultureIgnoreCase) ||
                                                        c.Name.Equals("Title", StringComparison.InvariantCultureIgnoreCase)).ToList();
                if (lookUpColumns.Count > 0)
                {
                    table.LookUpDisplayColumnId = lookUpColumns[0].Id;
                }
                else
                {
                    lookUpColumns = table.Columns.Where(c => c.DataType == TypeCode.String).ToList();
                    if (lookUpColumns.Count > 0)
                    {
                        table.LookUpDisplayColumnId = lookUpColumns[0].Id;
                    }
                    else
                    {
                        table.LookUpDisplayColumnId = table.Columns[0].Id;
                    }
                }
            }
        }
Пример #4
0
        /// <summary>
        /// This is to generate menu items and groups for navigation menu purpose.
        /// </summary>
        /// <param name="context">An instance of <see cref="DotWebDb"/>.</param>
        private void GenerateNavigationModules(DotWebDb context)
        {
            foreach (var tableMeta in schemaInfo.Tables)
            {
                string groupName = tableMeta.SchemaName == "dbo" ? schemaInfo.App.DefaultGroupName : tableMeta.SchemaName;
                var    group     = schemaInfo.App.Groups.FirstOrDefault(
                    g => g.AppId == appId && g.Name.Equals(groupName, StringComparison.InvariantCultureIgnoreCase));
                if (group == null)
                {
                    group = new ModuleGroup()
                    {
                        AppId   = appId,
                        Name    = groupName,
                        Title   = groupName,
                        OrderNo = schemaInfo.App.Groups.Count == 0 ? 1 : schemaInfo.App.Groups.Count + 1,
                    };
                    schemaInfo.App.Groups.Add(group);
                }

                var dbModule = context.Modules.Include(m => m.Group).SingleOrDefault(m => m.TableName.Equals(tableMeta.Name, StringComparison.InvariantCultureIgnoreCase) &&
                                                                                     m.Group.AppId == appId);

                if (dbModule == null)
                {
                    group.Modules.Add(new Module()
                    {
                        TableName  = tableMeta.Name,
                        Title      = tableMeta.Name.ToTitleCase(),
                        OrderNo    = group.Modules.Count == 0 ? 1 : group.Modules.Count + 1,
                        ModuleType = ModuleType.AutoGenerated
                    });
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Main entry for generation purpose.
        /// </summary>
        /// <param name="connectionStringName">Connection string name stored in configuration file.</param>
        public void GenerateFromDb(string connectionStringName)
        {
            dbConfig = new DotWebDb();
            EnsureApp(dbConfig);
            Inspect(connectionStringName);
            GenerateNavigationModules(dbConfig);
            SaveToConfig(true);
            DetermineColumnForLookUpDisplay(dbConfig);
            SaveToConfig(true);

            dbConfig.Dispose();
        }
Пример #6
0
        public void Generate(string assemblyName)
        {
            try
            {
                dbApp = GetDbContextFromAssembly(assemblyName);
                if (dbApp == null)
                {
                    throw new ArgumentException("ERROR: There is no dbContext descendant class in the assembly.");
                }

                dbConfig = new DotWebDb();

                if (string.IsNullOrEmpty(ConfigurationManager.AppSettings["appId"]))
                {
                    throw new ArgumentException("ERROR: appId must be specified in config.");
                }
                appId = int.Parse(ConfigurationManager.AppSettings["appId"]);
                app   = dbConfig.Apps.Find(appId);
                if (app == null)
                {
                    throw new ArgumentException(string.Format("ERROR: appId {0} not found in configdb.", appId));
                }

                EnsureOutputDirectory();
                EnsureTemplateDirectory();
                EmptyOutputDirectory();
                DeleteExistingNavigation();

                var properties = dbApp.GetDbSetProperties();
                var entitySets = properties.ToDictionary(x => x.Name, x => x.GetValue(dbApp, null));

                if (entitySets.Count() == 0)
                {
                    Console.WriteLine("WARNING: No entities in dbContext!");
                }
                else
                {
                    foreach (var entitySetName in entitySets.Keys)
                    {
                        var entityType = GetEntityTypeFromEntitySet(entitySets[entitySetName]);
                        InspectEntity(entitySetName, entityType);
                    }

                    foreach (var entitySetName in entitySets.Keys)
                    {
                        var entityType = GetEntityTypeFromEntitySet(entitySets[entitySetName]);
                        if (!entitiesMeta[entityType.Name].IsScaffold)
                        {
                            continue;
                        }
                        ReinspectEntity(entityType);
                    }

                    foreach (var entitySetName in entitySets.Keys)
                    {
                        var entityType = GetEntityTypeFromEntitySet(entitySets[entitySetName]);
                        if (!entitiesMeta[entityType.Name].IsScaffold)
                        {
                            continue;
                        }

                        ProcessEntity(entitySetName, entitiesMeta[entityType.Name]);
                    }
                }
            }
            finally
            {
                if (dbConfig != null)
                {
                    dbConfig.Dispose();
                }
                if (dbApp != null)
                {
                    dbApp.Dispose();
                }
            }
        }
Пример #7
0
        /// <summary>
        /// Save the inspection result to database.
        /// </summary>
        /// <param name="sharedContext">Indicates that dbContext used in the process is the shared one.</param>
        public void SaveToConfig(bool sharedContext = false)
        {
            if (string.IsNullOrEmpty(ConfigurationManager.AppSettings["appId"]))
            {
                throw new ArgumentException("appId must be specified in config.");
            }
            appId = int.Parse(ConfigurationManager.AppSettings["appId"].ToString());
            if (sharedContext && dbConfig == null)
            {
                throw new ArgumentException("Using shared context requires initialization.");
            }

            var context = dbConfig;

            if (!sharedContext)
            {
                context = new DotWebDb();
            }

            EnsureApp(context);

            // Save tables
            foreach (var tableMeta in SchemaInfo.Tables)
            {
                Console.WriteLine("Processing table " + tableMeta.Name);

                TableMeta dbTable = context.Tables
                                    .Include(t => t.Columns)
                                    .Include(t => t.Columns.Select(c => c.ReferenceTable))
                                    .Include(t => t.Children)
                                    .Include(t => t.Children.Select(c => c.Parent))
                                    .Include(t => t.Children.Select(c => c.Child))
                                    .Include(t => t.App)
                                    .SingleOrDefault(t => t.Name == tableMeta.Name && t.AppId == appId);

                var newTable = false;
                if (dbTable == null)
                {
                    // Add table
                    dbTable  = tableMeta;
                    newTable = true;
                }
                else
                {
                    // Update existing table
                    dbTable.SchemaName = tableMeta.SchemaName;
                }

                foreach (var columnMeta in tableMeta.Columns)
                {
                    Console.WriteLine("    Processing column " + columnMeta.Name + " of table " + tableMeta.Name);
                    ColumnMeta dbColumn  = context.Columns.SingleOrDefault(c => c.TableId == dbTable.Id && c.Name == columnMeta.Name);
                    var        newColumn = false;
                    if (dbColumn == null)
                    {
                        // Add columns
                        dbColumn       = columnMeta;
                        dbColumn.Table = dbTable;
                        newColumn      = true;
                    }
                    else
                    {
                        // Update existing column
                        dbColumn.DataType     = columnMeta.DataType;
                        dbColumn.IsForeignKey = columnMeta.IsForeignKey;
                        dbColumn.IsIdentity   = columnMeta.IsIdentity;
                        dbColumn.IsPrimaryKey = columnMeta.IsPrimaryKey;
                        dbColumn.IsRequired   = columnMeta.IsRequired;
                        dbColumn.MaxLength    = columnMeta.MaxLength;
                    }

                    if (columnMeta.ReferenceTable != null && (newColumn || dbColumn.ReferenceTable.Name != columnMeta.ReferenceTable.Name))
                    {
                        var dbRefTable = context.Tables.SingleOrDefault(t => tableMeta.AppId == appId &&
                                                                        t.Name.Equals(columnMeta.ReferenceTable.Name, StringComparison.InvariantCultureIgnoreCase));
                        if (dbRefTable != null)
                        {
                            dbColumn.ReferenceTable = dbRefTable;
                        }
                    }

                    if (newColumn && !newTable)
                    {
                        dbTable.Columns.Add(dbColumn);
                    }
                }

                // removes columns
                var removedColumns = new List <ColumnMeta>();
                foreach (var dbColumn in dbTable.Columns)
                {
                    ColumnMeta column = tableMeta.Columns.SingleOrDefault(c => c.Name.Equals(dbColumn.Name, StringComparison.InvariantCultureIgnoreCase));
                    if (column == null)
                    {
                        Console.WriteLine("    Removing column " + dbColumn.Name + " from table " + tableMeta.Name);
                        // column has been deleted or renamed, so delete related metadata
                        removedColumns.Add(dbColumn);
                    }
                }
                if (removedColumns.Count > 0)
                {
                    context.Columns.RemoveRange(removedColumns);
                }

                // Processing table meta relations
                foreach (var tableMetaRelation in tableMeta.Children)
                {
                    Console.WriteLine("    Processing relation " + tableMetaRelation.Name + " of table " + tableMeta.Name);
                    TableMetaRelation dbRelation = context.TableRelations.Include(r => r.Child).Include(r => r.Parent)
                                                   .SingleOrDefault(r => r.Name.Equals(tableMetaRelation.Name, StringComparison.InvariantCultureIgnoreCase));
                    if (dbRelation == null)
                    {
                        // Add relation
                        var dbChild = context.Tables.SingleOrDefault(t => t.AppId == appId && t.Name == tableMetaRelation.Child.Name);
                        if (dbChild != null)
                        {
                            tableMetaRelation.Child = dbChild;
                        }

                        var dbParent = context.Tables.SingleOrDefault(t => t.AppId == appId && t.Name == tableMetaRelation.Parent.Name);
                        if (dbParent != null)
                        {
                            tableMetaRelation.Parent = dbParent;
                        }
                        dbRelation = tableMetaRelation;
                        context.TableRelations.Add(dbRelation);
                    }
                    else
                    {
                        // Update existing relation
                        if (dbRelation.Child.Name != tableMetaRelation.Child.Name)
                        {
                            var dbChild = context.Tables.SingleOrDefault(t => t.AppId == appId && t.Name == tableMetaRelation.Child.Name);
                            if (dbChild != null)
                            {
                                dbRelation.Child = dbChild;
                            }
                        }

                        if (dbRelation.Parent.Name != tableMetaRelation.Parent.Name)
                        {
                            var dbParent = context.Tables.SingleOrDefault(t => t.AppId == appId && t.Name == tableMetaRelation.Parent.Name);
                            if (dbParent != null)
                            {
                                dbRelation.Parent = dbParent;
                            }
                        }
                    }
                }

                if (newTable)
                {
                    context.Tables.Add(dbTable);
                }

                if (context.ChangeTracker.HasChanges())
                {
                    context.SaveChanges();
                }
            }

            // Save navigation
            var newGroups = new List <ModuleGroup>();

            foreach (var group in schemaInfo.App.Groups)
            {
                var newModules = new List <Module>();
                var dbGroup    = context.ModuleGroups.SingleOrDefault(g => g.Name == group.Name && g.AppId == appId);
                foreach (var module in group.Modules)
                {
                    var dbModule = context.Modules.Include(m => m.Group).SingleOrDefault(m => m.ModuleType == ModuleType.AutoGenerated &&
                                                                                         m.TableName == module.TableName && m.Group.AppId == appId);
                    if (dbModule == null)
                    {
                        if (dbGroup != null)
                        {
                            module.Group = dbGroup;
                        }
                        newModules.Add(module);
                    }
                }

                if (newModules.Count > 0)
                {
                    context.Modules.AddRange(newModules);
                }
            }

            if (!sharedContext)
            {
                context.Dispose();
            }
        }