Beispiel #1
0
        public bool CompareModelToDatabase(DatabaseModel databaseModel)
        {
            var dbLogger = new CompareLogger(CompareType.DbContext, _dbContextName, _logs, _ignoreList, () => _hasErrors = true);

            //Check things about the database, such as sequences
            dbLogger.MarkAsOk(_dbContextName);
            CheckDatabaseOk(_logs.Last(), _model.Relational(), databaseModel);

            var tableDict = databaseModel.Tables.ToDictionary(x => x.Name);

            foreach (var entityType in _model.GetEntityTypes())
            {
                var eRel   = entityType.Relational();
                var logger = new CompareLogger(CompareType.Entity, entityType.ClrType.Name, _logs.Last().SubLogs, _ignoreList, () => _hasErrors = true);
                if (tableDict.ContainsKey(eRel.TableName))
                {
                    var databaseTable = tableDict[eRel.TableName];
                    //Checks for table matching
                    var log = logger.MarkAsOk(eRel.TableName);
                    logger.CheckDifferent(entityType.FindPrimaryKey().Relational().Name, databaseTable.PrimaryKey.Name,
                                          CompareAttributes.ConstraintName);
                    CompareColumns(log, entityType, databaseTable);
                    CompareForeignKeys(log, entityType, databaseTable);
                    CompareIndexes(log, entityType, databaseTable);
                }
                else
                {
                    logger.NotInDatabase(entityType.Relational().FormSchemaTable(), CompareAttributes.TableName);
                }
            }
            return(_hasErrors);
        }
        private void CompareColumns(CompareLog log, IEntityType entityType, DatabaseTable table)
        {
            var columnDict     = table.Columns.ToDictionary(x => x.Name, _caseComparer);
            var primaryKeyDict = table.PrimaryKey?.Columns.ToDictionary(x => x.Name, _caseComparer)
                                 ?? new Dictionary <string, DatabaseColumn>();

            var  efPKeyConstraintName = entityType.FindPrimaryKey().Relational().Name;
            bool pKeyError            = false;
            var  pKeyLogger           = new CompareLogger(CompareType.PrimaryKey, efPKeyConstraintName, log.SubLogs, _ignoreList,
                                                          () =>
            {
                pKeyError  = true;     //extra set of pKeyError
                _hasErrors = true;
            });

            pKeyLogger.CheckDifferent(efPKeyConstraintName, table.PrimaryKey?.Name ?? NoPrimaryKey,
                                      CompareAttributes.ConstraintName, _caseComparison);
            foreach (var property in entityType.GetProperties())
            {
                var pRel      = property.Relational();
                var colLogger = new CompareLogger(CompareType.Property, property.Name, log.SubLogs, _ignoreList, () => _hasErrors = true);

                if (columnDict.ContainsKey(pRel.ColumnName))
                {
                    if (!IgnorePrimaryKeyFoundInOwnedTypes(entityType.DefiningEntityType, table, property, entityType.FindPrimaryKey()))
                    {
                        var error = ComparePropertyToColumn(colLogger, property, columnDict[pRel.ColumnName]);
                        //check for primary key
                        if (property.IsPrimaryKey() != primaryKeyDict.ContainsKey(pRel.ColumnName))
                        {
                            if (!primaryKeyDict.ContainsKey(pRel.ColumnName))
                            {
                                pKeyLogger.NotInDatabase(pRel.ColumnName, CompareAttributes.ColumnName);
                                error = true;
                            }
                            else
                            {
                                pKeyLogger.ExtraInDatabase(pRel.ColumnName, CompareAttributes.ColumnName,
                                                           table.PrimaryKey.Name);
                            }
                        }

                        if (!error)
                        {
                            //There were no errors noted, so we mark it as OK
                            colLogger.MarkAsOk(pRel.ColumnName);
                        }
                    }
                }
                else
                {
                    colLogger.NotInDatabase(pRel.ColumnName, CompareAttributes.ColumnName);
                }
            }
            if (!pKeyError)
            {
                pKeyLogger.MarkAsOk(efPKeyConstraintName);
            }
        }
Beispiel #3
0
        private void CompareForeignKeys(CompareLog log, IEntityType entityType, DatabaseTable table)
        {
            var fKeyDict = table.ForeignKeys.ToDictionary(x => x.Name);

            foreach (var entityFKey in entityType.GetForeignKeys())
            {
                var entityFKeyprops = entityFKey.Properties;
                var constraintName  = entityFKey.Relational().Name;
                var logger          = new CompareLogger(CompareType.ForeignKey, constraintName, log.SubLogs, _ignoreList, () => _hasErrors = true);
                if (IgnoreForeignKeyIfInSameTable(entityType, entityFKey, table))
                {
                    continue;
                }
                if (fKeyDict.ContainsKey(constraintName))
                {
                    //Now check every foreign key
                    var error       = false;
                    var thisKeyCols = fKeyDict[constraintName].Columns.ToDictionary(x => x.Name);
                    foreach (var fKeyProp in entityFKeyprops)
                    {
                        var pRel = fKeyProp.Relational();
                        if (!thisKeyCols.ContainsKey(pRel.ColumnName))
                        {
                            logger.NotInDatabase(pRel.ColumnName);
                            error = true;
                        }
                    }
                    error |= logger.CheckDifferent(entityFKey.DeleteBehavior.ToString(),
                                                   fKeyDict[constraintName].OnDelete.ConvertReferentialActionToDeleteBehavior(entityFKey.DeleteBehavior),
                                                   CompareAttributes.DeleteBehaviour);
                    if (!error)
                    {
                        logger.MarkAsOk(constraintName);
                    }
                }
                else
                {
                    logger.NotInDatabase(constraintName, CompareAttributes.ConstraintName);
                }
            }
        }
Beispiel #4
0
        private void CompareIndexes(CompareLog log, IEntityType entityType, DatabaseTable table)
        {
            var indexDict = table.Indexes.ToDictionary(x => x.Name);

            foreach (var entityIdx in entityType.GetIndexes())
            {
                var entityIdxprops = entityIdx.Properties;
                var logger         = new CompareLogger(CompareType.Index, entityIdxprops.CombinedColNames(), log.SubLogs, _ignoreList, () => _hasErrors = true);
                var constraintName = entityIdx.Relational().Name;
                if (indexDict.ContainsKey(constraintName))
                {
                    //Now check every column in an index
                    var error       = false;
                    var thisIdxCols = indexDict[constraintName].Columns.ToDictionary(x => x.Name);
                    foreach (var idxProp in entityIdxprops)
                    {
                        var pRel = idxProp.Relational();
                        if (!thisIdxCols.ContainsKey(pRel.ColumnName))
                        {
                            logger.NotInDatabase(pRel.ColumnName);
                            error = true;
                        }
                    }
                    error |= logger.CheckDifferent(entityIdx.IsUnique.ToString(),
                                                   indexDict[constraintName].IsUnique.ToString(), CompareAttributes.Unique);
                    if (!error)
                    {
                        logger.MarkAsOk(constraintName);
                    }
                }
                else
                {
                    logger.NotInDatabase(constraintName, CompareAttributes.ConstraintName);
                }
            }
        }
        public bool CompareModelToDatabase(DatabaseModel databaseModel)
        {
            var dbLogger = new CompareLogger(CompareType.DbContext, _dbContextName, _logs, _ignoreList, () => _hasErrors = true);

            //Check things about the database, such as sequences
            dbLogger.MarkAsOk(_dbContextName);
            CheckDatabaseOk(_logs.Last(), _model.Relational(), databaseModel);

            var tableDict = databaseModel.Tables.ToDictionary(x => x.FormSchemaTable(databaseModel.DefaultSchema), _caseComparer);
            var dbQueries = _model.GetEntityTypes().Where(x => x.IsQueryType).ToList();

            if (dbQueries.Any())
            {
                dbLogger.Warning("EfSchemaCompare does not check DbQuery types", null, string.Join(", ", dbQueries.Select(x => x.ClrType.Name)));
            }
            foreach (var entityType in _model.GetEntityTypes().Where(x => !x.IsQueryType))
            {
                var eRel   = entityType.Relational();
                var logger = new CompareLogger(CompareType.Entity, entityType.ClrType.Name, _logs.Last().SubLogs, _ignoreList, () => _hasErrors = true);
                if (tableDict.ContainsKey(eRel.FormSchemaTable()))
                {
                    var databaseTable = tableDict[eRel.FormSchemaTable()];
                    //Checks for table matching
                    var log = logger.MarkAsOk(eRel.FormSchemaTable());
                    logger.CheckDifferent(entityType.FindPrimaryKey()?.Relational().Name ?? NoPrimaryKey,
                                          databaseTable.PrimaryKey?.Name ?? NoPrimaryKey,
                                          CompareAttributes.ConstraintName, _caseComparison);
                    CompareColumns(log, entityType, databaseTable);
                    CompareForeignKeys(log, entityType, databaseTable);
                    CompareIndexes(log, entityType, databaseTable);
                }
                else
                {
                    logger.NotInDatabase(entityType.Relational().FormSchemaTable(), CompareAttributes.TableName);
                }
            }
            return(_hasErrors);
        }