public void FixtureSetup()
 {
     using (var db = new TestEf6SchemaCompareDb())
     {
         var decoder = new Ef6MetadataDecoder(Assembly.GetAssembly(typeof(DataTop)));
         _efInfos = decoder.GetAllEfTablesWithColInfo(db);
         var allSqlInfo = SqlAllInfo.SqlAllInfoFactory(db.Database.Connection.ConnectionString);
         _checker = new EfRelationshipChecker(_efInfos, allSqlInfo, allSqlInfo.TableInfos);     //NOTE: we aren't able to filter potentialManyToManyTables
     }
 }
Example #2
0
        public ISuccessOrErrors CompareEfWithSql(IList <EfTableInfo> efInfos, SqlAllInfo allSqlInfo)
        {
            var status = SuccessOrErrors.Success("All Ok");

            //first we compare the ef table columns with the SQL table columns
            foreach (var efInfo in efInfos)
            {
                if (!_sqlInfoDict.ContainsKey(efInfo.CombinedName))
                {
                    status.AddSingleError(
                        "Missing Table: The SQL {0} does not contain a table called {1}. Needed by EF class {2}.",
                        _sqlDbRefString, efInfo.CombinedName, efInfo.ClrClassType.Name);
                }
                else
                {
                    //has table, so compare the columns/properties
                    var sqlTableInfo = _sqlInfoDict[efInfo.CombinedName];
                    _sqlInfoDict.Remove(efInfo.CombinedName);

                    //we create a dict, which we check. As we find columns we remove them
                    var sqlColsDict = sqlTableInfo.ColumnInfos.ToDictionary(x => x.ColumnName);

                    foreach (var clrCol in efInfo.NormalCols)
                    {
                        if (!sqlColsDict.ContainsKey(clrCol.SqlColumnName))
                        {
                            status.AddSingleError(
                                "Missing Column: The SQL {0} table {1} does not contain a column called {2}. Needed by EF class {3}.",
                                _sqlDbRefString, efInfo.CombinedName, clrCol.SqlColumnName, efInfo.ClrClassType.Name);
                        }
                        else
                        {
                            //check the columns match
                            var sqlCol = sqlColsDict[clrCol.SqlColumnName];
                            sqlColsDict.Remove(clrCol.SqlColumnName);            //remove it as it has been used

                            status.Combine(CheckColumn(sqlCol, clrCol, efInfo.CombinedName));
                        }
                    }
                    //At the end we check if any sql columns are left
                    if (sqlColsDict.Any())
                    {
                        foreach (var missingCol in sqlColsDict.Values)
                        {
                            status.AddWarning("SQL {0} table {1} has a column called {2} (.NET type {3}) that EF does not access.",
                                              _sqlDbRefString, efInfo.CombinedName, missingCol.ColumnName, missingCol.SqlTypeName.SqlToClrType(missingCol.IsNullable));
                        }
                    }
                }
            }

            //now we compare the EF relationships with the SQL foreign keys
            //we do this here because we now have the tables that wren't mentioned in EF,
            //which are the tables that EF will automatically add to handle many-many relationships.
            var relChecker = new EfRelationshipChecker(efInfos, allSqlInfo, _sqlInfoDict.Values.ToList());

            foreach (var efInfo in efInfos)
            {
                //now we check the relationships
                foreach (var relationCol in efInfo.RelationshipCols)
                {
                    var relStatus = relChecker.CheckEfRelationshipToSql(efInfo, relationCol);
                    status.Combine(relStatus);
                    if (relStatus.IsValid && relStatus.Result != null)
                    {
                        //It has found a many-to-many table which we need to remove so that it does not show a warning at the end
                        _sqlInfoDict.Remove(relStatus.Result);
                    }
                }
            }

            return(status);
        }