// Выбор площадки из справочника.
        // (! будет время  - выполнить рефакторинг загрузки справочников).
        private void itbPlace_ButtonClick(object sender, EventArgs e)
        {
            try
            {
                using (var dlg = new TableSelectionForm
                {
                    Name = "dlgPlace",
                    Text = "Выбор места",
                    ValueColumnName = "nUnitId",
                    Width = 600,
                    Height = 380
                })
                {
                    dlg.AddTextColumn("Наименование места",
                                      "cNameUnit", DataGridViewAutoSizeColumnMode.Fill, 100, 100);
                    SQLCoreInterfaceHelper.InitializeChildSQLCore(dlg, this);

                    var itb = (ItmTextBox)sender;
                    dlg.DataSource    = itb.DataSource;
                    dlg.SelectedValue = itb.SelectedValue;
                    if (dlg.ShowDialog(this) == DialogResult.OK)
                    {
                        itb.SelectedValue = dlg.SelectedValue;
                    }
                }
            }
            catch (Exception ex)
            {
                // public class MessageBoxes from Itm.WClient.Com;
                MessageBoxes.Error(this, ex, "Ошибка выбора площадки!");
                return;
            }
        }
Beispiel #2
0
        bool LoadModelsFromDb()
        {
            //Supports only MSSQL for now..
            var          schemaDiscoverer = new MSSQLSchemaDiscover(connSettings);
            var          allTables        = schemaDiscoverer.DiscoverTables();
            List <Table> modelTables      = new List <Table>();
            List <Table> mappingTables    = new List <Table>();

            foreach (Table t in allTables)
            {
                if (t.Columns.Count == 2 && t.Columns.All(c => c.IsPrimaryKey))
                {
                    mappingTables.Add(t);
                }
                else
                {
                    modelTables.Add(t);
                }
            }

            var          classesInStore        = diagram.Store.ElementDirectory.FindElements <ModelClass>().ToList();
            List <Table> tablesSelected        = null;
            bool         autoDetectInheritance = true;
            string       tablePrefix           = "";

            var customInheritances = new Dictionary <string, string>();

            if (this.FullDatabaseReload)
            {
                tablesSelected = new List <Table>(modelTables);

                var origCursor2 = Cursor.Current;
                try
                {
                    Cursor.Current = Cursors.WaitCursor;
                    using (var tx = diagram.Store.TransactionManager.BeginTransaction("FullScope", false))
                    {
                        classesInStore.ForEach(c =>
                        {
                            if (tablesSelected.Find(t => t.Name == c.TableName) != null)
                            {
                                customInheritances.Add(c.TableName, c.DerivesOrImplements);
                                c.Delete();
                            }
                        });
                        if (tx.HasPendingChanges)
                        {
                            tx.Commit();
                        }
                    }
                }
                finally
                {
                    Cursor.Current = origCursor2;
                }
                classesInStore = diagram.Store.ElementDirectory.FindElements <ModelClass>().ToList();
            }
            else
            {
                var tableSelectionDlg = new TableSelectionForm();
                tableSelectionDlg.Initialize(modelTables, classesInStore.Select(c => c.TableName).ToList());
                if (tableSelectionDlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    tablesSelected        = tableSelectionDlg.SelectedTables;
                    autoDetectInheritance = tableSelectionDlg.AutoDetectInheritance;
                    tablePrefix           = tableSelectionDlg.TablePrefix;
                }
                else
                {
                    return(false);
                }
            }
            var associations = schemaDiscoverer.DiscoverAssociations();

            var associationsInStore = diagram.Store.ElementDirectory.FindElements <AgileFx.AgileModeler.Association>().ToList();
            var inheritancesInStore = diagram.Store.ElementDirectory.FindElements <Inheritance>().ToList();

            Func <string, ModelClass> findClass = tableName => classesInStore.Find(c => c.TableName == tableName);
            Func <string, AgileFx.AgileModeler.Association> findAssociation = assocName => associationsInStore.Find(a => a.Name == assocName);

            Func <string, Table>         findTable          = tableName => tablesSelected.Find(t => t.Name == tableName);
            Func <Table, string, Column> getColumnFromTable = (table, columnName) => table.Columns.Find(c => c.Name == columnName);

            Func <string, string, bool> isColumnPrimary = (tableName, columnName) =>
            {
                var t = findTable(tableName);
                if (t != null)
                {
                    return(getColumnFromTable(t, columnName).IsPrimaryKey);
                }
                else
                {
                    var c = findClass(tableName);
                    return((c.Baseclass != null)
                        ? inheritancesInStore.Find(inh => inh.Subclass == c).DerivedClassPrimaryKeyColumn == columnName
                        : c.Fields.Find(f => f.ColumnName == columnName).IsPrimaryKey);
                }
            };

            var unicodeDbTypes     = new[] { DatabaseType.NChar, DatabaseType.NText, DatabaseType.NVarChar };
            var fixedLengthDbTypes = new[] { DatabaseType.Char, DatabaseType.NChar };
            var nonComparableTypes = new[] { BuiltInTypes.Binary, BuiltInTypes.Timestamp };
            var pagedStringTypes   = new[] { DatabaseType.NText, DatabaseType.Text };

            Action <ModelField, Column> loadFieldFromColumn = (field, col) =>
            {
                field.IsPrimaryKey  = col.IsPrimaryKey;
                field.Nullable      = col.IsNullable;
                field.Type          = col.DbDataType.Type == typeof(byte[]) ? BuiltInTypes.Binary : (BuiltInTypes)Enum.Parse(typeof(BuiltInTypes), col.DbDataType.Type.Name);
                field.IsDbGenerated = col.IsPrimaryKey;
                field.IsFixedLength = fixedLengthDbTypes.Contains(col.DbDataType.ProviderType);
                field.IsUnicode     = unicodeDbTypes.Contains(col.DbDataType.ProviderType);
                field.IsUnique      = col.IsUnique;
                field.MaxLength     = pagedStringTypes.Contains(col.DbDataType.ProviderType) ? 0 : col.DbDataType.Size;
                field.IsIdentity    = col.IsIdentity;
                if (nonComparableTypes.Any(t => t == field.Type) ||
                    (field.Type == BuiltInTypes.String && field.MaxLength == 0))
                {
                    field.UpdateCheck = ConcurrencyCheckFrequency.Never;
                }
            };

            Action <Column, ModelClass> addFieldFromColumn = (col, modelClass) =>
            {
                var field = new ModelField(diagram.Store)
                {
                    ColumnName = col.Name,
                    Name       = ModelUtil.GetMemberName(GetMemberName(col.Name, false), modelClass, false)
                };
                modelClass.Fields.Add(field);
                loadFieldFromColumn(field, col);
            };

            Action <ModelClass, string> clearTempProp = (modelClass, association) => modelClass.NavigationProperties.ToList().ForEach(np =>
            {
                if (np.Association == association && np.Type == "Temporary")
                {
                    np.Delete();
                }
            });

            var origCursor = Cursor.Current;

            try
            {
                Cursor.Current = Cursors.WaitCursor;
                var selectedTableNames = tablesSelected.Select(t => t.Name).ToList();
                var tablesInScope      = classesInStore.Select(c => c.TableName).Union(selectedTableNames).ToList();

                //At least one end of the mapping table should be a table in scope
                var mapTableAssociations = associations.Where(a => mappingTables.Any(t => t.Name == a.ChildTable) &&
                                                              tablesInScope.Contains(a.ParentTable)).ToList();

                //Filter associations involving only tables newly added or already in store
                associations.ToList().ForEach(a =>
                {
                    //At least one end of the association should be a selected table
                    //while the other end could be an existing table in store.
                    if (!((selectedTableNames.Contains(a.ParentTable) && tablesInScope.Contains(a.ChildTable)) ||
                          (tablesInScope.Contains(a.ParentTable) && selectedTableNames.Contains(a.ChildTable))))
                    {
                        associations.Remove(a);
                    }
                });


                var orderedTables    = new List <Table>(tablesSelected);
                var inheritanceTable = new Dictionary <string, Microsoft.Practices.RepositoryFactory.SchemaDiscovery.ObjectModel.Base.Association>();
                if (autoDetectInheritance)
                {
                    associations.ToList().ForEach(assoc =>
                    {
                        if (isColumnPrimary(assoc.ChildTable, assoc.ChildMember) && assoc.ChildTable != assoc.ParentTable)
                        {
                            inheritanceTable.Add(assoc.ChildTable, assoc);
                            associations.Remove(assoc);
                        }
                    });
                    var newList = new List <Table>();
                    while (orderedTables.Count > 0)
                    {
                        orderedTables.ToList().ForEach(t =>
                        {
                            if (!inheritanceTable.ContainsKey(t.Name) ||
                                newList.Any(nt => nt.Name == inheritanceTable[t.Name].ParentTable) ||
                                !orderedTables.Any(ot => ot.Name == inheritanceTable[t.Name].ParentTable))
                            {
                                newList.Add(t);
                                orderedTables.Remove(t);
                            }
                        });
                    }
                    orderedTables = newList;
                }

                orderedTables.ForEach(t =>
                {
                    using (var tx = diagram.Store.TransactionManager.BeginTransaction("AddModel", false))
                    {
                        var cls = findClass(t.Name);
                        if (cls == null)
                        {
                            cls = new ModelClass(diagram.Store)
                            {
                                Name = GetClassName(t.Name, tablePrefix), TableName = t.Name
                            };
                            ((ModelRoot)diagram.ModelElement).Types.Add(cls);
                            classesInStore.Add(cls);
                            if (this.FullDatabaseReload && customInheritances.ContainsKey(cls.TableName))
                            {
                                cls.DerivesOrImplements = customInheritances[cls.TableName];
                            }
                        }
                        if (inheritanceTable.ContainsKey(t.Name))
                        {
                            var assoc = inheritanceTable[t.Name];
                            if (cls.Baseclass == null)
                            {
                                var existingAssociation = findAssociation(assoc.Name);
                                if (existingAssociation != null)
                                {
                                    DeleteAssociation(existingAssociation);
                                }

                                new Inheritance(findClass(assoc.ParentTable), cls)
                                {
                                    DerivedClassPrimaryKeyColumn = assoc.ChildMember,
                                    BaseClassPrimaryKeyColumn    = assoc.ParentMember
                                };
                            }
                            else
                            {
                                associations.Add(assoc);
                            }
                        }

                        foreach (Column col in GetOrderedColumns(t))
                        {
                            var field = cls.Fields.Find(f => f.ColumnName == col.Name);
                            if (field != null && !field.IsEdited)
                            {
                                loadFieldFromColumn(field, col);
                            }
                            else
                            {
                                addFieldFromColumn(col, cls);
                            }
                        }
                        if (cls.Baseclass != null)
                        {
                            cls.Fields.Where(f => f.IsPrimaryKey).ToList().ForEach(f => f.Delete());
                        }

                        Func <string, string> findClassOrTableName = tableName =>
                        {
                            var c = findClass(tableName);
                            return((c != null) ? c.Name : GetClassName(tableName, tablePrefix));
                        };
                        associations.Where(a => findAssociation(a.Name) == null).ToList()
                        .ForEach(a =>
                        {
                            if (a.ParentTable == cls.TableName)
                            {
                                cls.NavigationProperties.Add(new NavigationProperty(diagram.Store)
                                {
                                    Name = ModelUtil.GetMemberName(findClassOrTableName(a.ChildTable), cls, true), Association = a.Name, Type = "Temporary"
                                });
                            }
                            else if (a.ChildTable == cls.TableName)
                            {
                                cls.NavigationProperties.Add(new NavigationProperty(diagram.Store)
                                {
                                    Name = ModelUtil.GetMemberName(findClassOrTableName(a.ParentTable), cls, false), Association = a.Name, Type = "Temporary"
                                });
                            }
                        });
                        mapTableAssociations.Where(a => findAssociation(a.ChildTable) == null).ToList()
                        .ForEach(a =>
                        {
                            if (a.ParentTable == cls.TableName)
                            {
                                var end2Assoc = mapTableAssociations.Find(x => x.Name != a.Name && x.ChildTable == a.ChildTable);
                                if (end2Assoc != null)
                                {
                                    cls.NavigationProperties.Add(new NavigationProperty(diagram.Store)
                                    {
                                        Name = ModelUtil.GetMemberName(findClassOrTableName(end2Assoc.ParentTable), cls, true), Association = a.ChildTable, Type = "Temporary"
                                    });
                                }
                            }
                        });

                        tx.Commit();
                    }
                });

                using (var tx = diagram.Store.TransactionManager.BeginTransaction("AddAssociations", false))
                {
                    mappingTables.ForEach(t =>
                    {
                        if (findAssociation(t.Name) != null)
                        {
                            return;
                        }
                        var field1Association = mapTableAssociations.Find(a => a.ChildTable == t.Name && a.ChildMember == t.Columns[0].Name);
                        var field2Association = mapTableAssociations.Find(a => a.ChildTable == t.Name && a.ChildMember == t.Columns[1].Name);
                        if (field1Association != null && field2Association != null)
                        {
                            var class1 = findClass(field1Association.ParentTable);
                            var class2 = findClass(field2Association.ParentTable);

                            if (class1 == null || class2 == null)
                            {
                                return;
                            }

                            clearTempProp(class1, t.Name);
                            var field1AssocNameParts = field1Association.Name.Split('_');
                            var class1NavProp        = new NavigationProperty(diagram.Store)
                            {
                                ModelClass   = class1,
                                Name         = (field1AssocNameParts.Length >= 5) ? field1AssocNameParts[4] : ModelUtil.GetMemberName(class2.Name, class1, true),
                                Type         = "ICollection<" + class2.Name + ">",
                                Multiplicity = AgileFx.AgileModeler.Multiplicity.ZeroMany,
                                Association  = t.Name,
                            };

                            clearTempProp(class2, t.Name);
                            var field2AssocNameParts = field2Association.Name.Split('_');
                            var class2NavProp        = new NavigationProperty(diagram.Store)
                            {
                                ModelClass   = class2,
                                Name         = (field2AssocNameParts.Length >= 5) ? field2AssocNameParts[4] : ModelUtil.GetMemberName(class1.Name, class2, true),
                                Type         = "ICollection<" + class1.Name + ">",
                                Multiplicity = AgileFx.AgileModeler.Multiplicity.ZeroMany,
                                Association  = t.Name
                            };

                            associations.Remove(field1Association);
                            associations.Remove(field2Association);
                            Func <string, string> getM2MFieldName = colName => Regex.Match(colName, ".+_?id$", RegexOptions.IgnoreCase).Success ? colName : colName + "Id";
                            new AgileFx.AgileModeler.Association(class1, class2)
                            {
                                Name = t.Name,

                                End1Multiplicity       = AgileFx.AgileModeler.Multiplicity.ZeroMany,
                                End1RoleName           = class1NavProp.ModelClass.Name,
                                End1NavigationProperty = class1NavProp.Name,

                                End2Multiplicity       = AgileFx.AgileModeler.Multiplicity.ZeroMany,
                                End2RoleName           = class2NavProp.ModelClass.Name,
                                End2NavigationProperty = class2NavProp.Name,

                                ManyToManyMappingTable           = t.Name,
                                End1ManyToManyMappingColumn      = t.Columns[0].Name,
                                End1ManyToManyFieldName          = getM2MFieldName(t.Columns[0].Name),
                                End1ManyToManyNavigationProperty = GetMemberName(t.Columns[0].Name, true),
                                End2ManyToManyMappingColumn      = t.Columns[1].Name,
                                End2ManyToManyFieldName          = getM2MFieldName(t.Columns[1].Name),
                                End2ManyToManyNavigationProperty = GetMemberName(t.Columns[1].Name, true),
                            };
                        }
                    });

                    associations.ForEach(assoc =>
                    {
                        var parentClass = findClass(assoc.ParentTable);
                        var childClass  = findClass(assoc.ChildTable);

                        var foreignkeyField = childClass.Fields.Find(f => f.ColumnName == assoc.ChildMember);
                        if (foreignkeyField != null && !foreignkeyField.IsEdited && !foreignkeyField.Name.ToLower().EndsWith("id"))
                        {
                            foreignkeyField.Name += "Id";
                        }
                        var isOneToOneAssociation  = (foreignkeyField != null && foreignkeyField.IsPrimaryKey);
                        var primaryEndMultiplicity = isOneToOneAssociation ? Multiplicity.ZeroOne : Multiplicity.ZeroMany;

                        if (findAssociation(assoc.Name) != null)
                        {
                            return;
                        }

                        var assocNameParts = assoc.Name.Split('_');
                        if (assocNameParts.Length > 5)
                        {
                            isOneToOneAssociation  = true;
                            primaryEndMultiplicity = assocNameParts[5].StartsWith("ZeroOne") ? Multiplicity.ZeroOne : Multiplicity.One;
                        }
                        clearTempProp(parentClass, assoc.Name);
                        var parentNavProp = new NavigationProperty(diagram.Store)
                        {
                            ModelClass   = parentClass,
                            Name         = (assocNameParts.Length >= 5) ? assocNameParts[4] : ModelUtil.GetMemberName(assoc.ChildTable, parentClass, true),
                            Type         = isOneToOneAssociation ? childClass.Name : "ICollection<" + childClass.Name + ">",
                            Multiplicity = primaryEndMultiplicity,
                            Association  = assoc.Name,
                        };

                        clearTempProp(childClass, assoc.Name);
                        var childNavProp = new NavigationProperty(diagram.Store)
                        {
                            ModelClass       = childClass,
                            Name             = (assocNameParts.Length >= 5) ? assocNameParts[2] : ModelUtil.GetMemberName(assoc.ParentTable, childClass, false),
                            Type             = parentClass.Name,
                            Multiplicity     = findTable(assoc.ChildTable).Columns.Find(c => c.Name == assoc.ChildMember).IsNullable ? Multiplicity.ZeroOne : Multiplicity.One,
                            Association      = assoc.Name,
                            IsForeignkey     = true,
                            ForeignkeyColumn = assoc.ChildMember,
                        };

                        new AgileFx.AgileModeler.Association(parentClass, childClass)
                        {
                            Name = assoc.Name,

                            End1Multiplicity       = childNavProp.Multiplicity,
                            End1RoleName           = parentNavProp.ModelClass.Name,
                            End1NavigationProperty = parentNavProp.Name,

                            End2Multiplicity       = parentNavProp.Multiplicity,
                            End2RoleName           = childNavProp.ModelClass.Name,
                            End2NavigationProperty = childNavProp.Name
                        };
                    });
                    if (tx.HasPendingChanges)
                    {
                        tx.Commit();
                    }
                }

                return(true);
            }
            finally
            {
                Cursor.Current = origCursor;
            }
        }