diff --git a/.github/workflows/github-actions-release.yml b/.github/workflows/github-actions-release.yml index 667c94c..3d176f0 100644 --- a/.github/workflows/github-actions-release.yml +++ b/.github/workflows/github-actions-release.yml @@ -7,7 +7,7 @@ on: type: string description: The version of the library required: true - default: 2.2.0 + default: 2.3.0 VersionSuffix: type: string description: The version suffix of the library (for example rc.1) diff --git a/CodeCoverage.runsettings b/CodeCoverage.runsettings index c9bffdc..0f42dd3 100644 --- a/CodeCoverage.runsettings +++ b/CodeCoverage.runsettings @@ -31,12 +31,6 @@ - - - .*PosInformatique.* - - - True True diff --git a/Directory.Packages.props b/Directory.Packages.props index 0921fcd..546b9aa 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -3,16 +3,16 @@ true - - + + - + - - + + \ No newline at end of file diff --git a/samples/DemoApp.DataAccessLayer.Migrations.Tests/DemoApp.DataAccessLayer.Migrations.Tests.csproj b/samples/DemoApp.DataAccessLayer.Migrations.Tests/DemoApp.DataAccessLayer.Migrations.Tests.csproj index 2d29966..88e4e6d 100644 --- a/samples/DemoApp.DataAccessLayer.Migrations.Tests/DemoApp.DataAccessLayer.Migrations.Tests.csproj +++ b/samples/DemoApp.DataAccessLayer.Migrations.Tests/DemoApp.DataAccessLayer.Migrations.Tests.csproj @@ -10,12 +10,18 @@ - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/samples/DemoApp.DataAccessLayer.Tests/DemoApp.DataAccessLayer.Tests.csproj b/samples/DemoApp.DataAccessLayer.Tests/DemoApp.DataAccessLayer.Tests.csproj index 2ebda52..f0a6030 100644 --- a/samples/DemoApp.DataAccessLayer.Tests/DemoApp.DataAccessLayer.Tests.csproj +++ b/samples/DemoApp.DataAccessLayer.Tests/DemoApp.DataAccessLayer.Tests.csproj @@ -20,12 +20,18 @@ - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/samples/Directory.Packages.props b/samples/Directory.Packages.props index 17c9a48..c9ab5b4 100644 --- a/samples/Directory.Packages.props +++ b/samples/Directory.Packages.props @@ -3,17 +3,17 @@ true - - + + - - - + + + - + - - + + \ No newline at end of file diff --git a/src/Testing.Databases.SqlServer/Comparer/SqlObjectComparer.cs b/src/Testing.Databases.SqlServer/Comparer/SqlObjectComparer.cs index 35abcf8..433e1af 100644 --- a/src/Testing.Databases.SqlServer/Comparer/SqlObjectComparer.cs +++ b/src/Testing.Databases.SqlServer/Comparer/SqlObjectComparer.cs @@ -6,6 +6,8 @@ namespace PosInformatique.Testing.Databases.SqlServer { + using System.Diagnostics.CodeAnalysis; + internal sealed class SqlObjectComparer : ISqlObjectVisitor { private readonly SqlObject source; @@ -73,7 +75,7 @@ public static IList Compare(IReadOnlyList source, this.CompareProperty(column, t => t.Precision, nameof(column.Precision)), this.CompareProperty(column, t => t.Scale, nameof(column.Scale)), this.CompareProperty(column, t => t.IsNullable, nameof(column.IsNullable)), - this.CompareProperty(column, t => t.IsIdentity, nameof(column.IsIdentity)), + this.CompareProperty(column, t => t.Identity, nameof(column.Identity), equalityComparer: SqlColumnIdentityComparer.Instance), this.CompareProperty(column, t => t.CollationName, nameof(column.CollationName)), this.CompareProperty(column, t => t.IsComputed, nameof(column.IsComputed)), this.CompareProperty(column, t => TsqlCodeHelper.RemoveNotUsefulCharacters(t.ComputedExpression), nameof(column.ComputedExpression), t => t.ComputedExpression)); @@ -331,7 +333,7 @@ private static IReadOnlyList GetPropertyDifferences return objects.SingleOrDefault(o => Equals(keySelector(o), value)); } - private SqlObjectPropertyDifference? CompareProperty(TSqlObject target, Func propertyValueForComparison, string name, Func? propertyValueToDisplay = null) + private SqlObjectPropertyDifference? CompareProperty(TSqlObject target, Func propertyValueForComparison, string name, Func? propertyValueToDisplay = null, IEqualityComparer? equalityComparer = null) where TSqlObject : SqlObject { var source = (TSqlObject)this.source; @@ -344,7 +346,12 @@ private static IReadOnlyList GetPropertyDifferences var sourceValue = propertyValueForComparison(source); var targetValue = propertyValueForComparison(target); - if (!Equals(sourceValue, targetValue)) + if (equalityComparer is null) + { + equalityComparer = EqualityComparer.Default; + } + + if (!equalityComparer.Equals(sourceValue, targetValue)) { return new SqlObjectPropertyDifference(name, propertyValueToDisplay(source), propertyValueToDisplay(target)); } @@ -364,5 +371,50 @@ private static IReadOnlyList GetPropertyDifferences return new SqlObjectDifferences((TSqlObject)this.source, target, SqlObjectDifferenceType.Different, properties!); } + + private sealed class SqlColumnIdentityComparer : IEqualityComparer + { + private SqlColumnIdentityComparer() + { + } + + public static SqlColumnIdentityComparer Instance { get; } = new SqlColumnIdentityComparer(); + + public bool Equals(SqlColumnIdentity? x, SqlColumnIdentity? y) + { + if (x is null) + { + if (y is null) + { + return true; + } + + return false; + } + + if (y is null) + { + return false; + } + + if (x.Seed != y.Seed) + { + return false; + } + + if (x.Increment != y.Increment) + { + return false; + } + + return true; + } + + [ExcludeFromCodeCoverage] + public int GetHashCode(SqlColumnIdentity? obj) + { + throw new NotImplementedException(); + } + } } } diff --git a/src/Testing.Databases.SqlServer/ObjectModel/SqlColumn.cs b/src/Testing.Databases.SqlServer/ObjectModel/SqlColumn.cs index e30a345..0beb1bd 100644 --- a/src/Testing.Databases.SqlServer/ObjectModel/SqlColumn.cs +++ b/src/Testing.Databases.SqlServer/ObjectModel/SqlColumn.cs @@ -70,7 +70,7 @@ internal SqlColumn( /// /// Gets a value indicating whether if the column is identity. /// - public bool IsIdentity { get; internal set; } + public SqlColumnIdentity? Identity { get; internal set; } /// /// Gets a value indicating whether if the column is computed. diff --git a/src/Testing.Databases.SqlServer/ObjectModel/SqlColumnIdentity.cs b/src/Testing.Databases.SqlServer/ObjectModel/SqlColumnIdentity.cs new file mode 100644 index 0000000..e49e82b --- /dev/null +++ b/src/Testing.Databases.SqlServer/ObjectModel/SqlColumnIdentity.cs @@ -0,0 +1,42 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) P.O.S Informatique. All rights reserved. +// +//----------------------------------------------------------------------- + +namespace PosInformatique.Testing.Databases +{ + /// + /// Represents the information when + /// a is an IDENTITY column. + /// + public class SqlColumnIdentity + { + /// + /// Initializes a new instance of the class. + /// + /// Seed of the IDENTITY column. + /// Increment of the IDENTITY column. + public SqlColumnIdentity(int seed, int increment) + { + this.Seed = seed; + this.Increment = increment; + } + + /// + /// Gets the seed of the IDENTITY column. + /// + public int Seed { get; } + + /// + /// Gets the increment of the IDENTITY column. + /// + public int Increment { get; } + + /// + public override string ToString() + { + return $"(Seed: {this.Seed}, Increment: {this.Increment})"; + } + } +} diff --git a/src/Testing.Databases.SqlServer/SqlServerDatabaseObjectExtensions.cs b/src/Testing.Databases.SqlServer/SqlServerDatabaseObjectExtensions.cs index 746e134..0b9138b 100644 --- a/src/Testing.Databases.SqlServer/SqlServerDatabaseObjectExtensions.cs +++ b/src/Testing.Databases.SqlServer/SqlServerDatabaseObjectExtensions.cs @@ -298,13 +298,18 @@ private static async Task> GetColumnsAsync(SqlServerDataba [c].[collation_name] AS [CollationName], [c].[is_nullable] AS [IsNullable], [c].[is_identity] AS [IsIdentity], + [ic].[seed_value] AS [IdentitySeed], + [ic].[increment_value] AS [IdentityIncrement], [c].[is_computed] AS [IsComputed], [cc].[definition] AS [ComputedExpression] FROM [sys].[columns] AS [c] LEFT OUTER JOIN [sys].[computed_columns] AS [cc] - ON ([c].[object_id] = [cc].[object_id] AND [c].[column_id] = [cc].[column_id]), + ON ([c].[object_id] = [cc].[object_id] AND [c].[column_id] = [cc].[column_id]) + LEFT OUTER JOIN + [sys].[identity_columns] AS [ic] + ON ([c].[object_id] = [ic].[object_id] AND [c].[column_id] = [ic].[column_id]), [sys].[tables] AS [t], [sys].[types] AS [ty] WHERE @@ -500,6 +505,13 @@ private static SqlCheckConstraint ToCheckConstraint(DataRow row) private static SqlColumn ToColumn(DataRow row, DataRow? defaultConstraintRow) { + SqlColumnIdentity? identity = null; + + if ((bool)row["IsIdentity"] == true) + { + identity = new SqlColumnIdentity((int)row["IdentitySeed"], (int)row["IdentityIncrement"]); + } + return new SqlColumn( (string)row["Name"], Convert.ToInt32(row["Position"], CultureInfo.InvariantCulture), @@ -512,7 +524,7 @@ private static SqlColumn ToColumn(DataRow row, DataRow? defaultConstraintRow) ComputedExpression = NullIfDbNull(row["ComputedExpression"]), DefaultConstraint = defaultConstraintRow != null ? ToDefaultConstraint(defaultConstraintRow) : null, IsComputed = (bool)row["IsComputed"], - IsIdentity = (bool)row["IsIdentity"], + Identity = identity, IsNullable = (bool)row["IsNullable"], }; } diff --git a/tests/Testing.Databases.SqlServer.Tests.Source/Tables/TableDifference.sql b/tests/Testing.Databases.SqlServer.Tests.Source/Tables/TableDifference.sql index 0c44ec2..27e8cb3 100644 --- a/tests/Testing.Databases.SqlServer.Tests.Source/Tables/TableDifference.sql +++ b/tests/Testing.Databases.SqlServer.Tests.Source/Tables/TableDifference.sql @@ -5,7 +5,7 @@ [MaxLength] VARCHAR(50) NOT NULL, [Precision] DECIMAL(10, 2) NOT NULL, [Scale] DECIMAL(10, 2) NOT NULL, - [Identity] INT NOT NULL IDENTITY, + [Identity] INT NOT NULL IDENTITY (2, 3), [ForeignKeyId] INT NULL, [Computed] AS [Scale] + [Precision], [SourceColumn] INT NOT NULL, diff --git a/tests/Testing.Databases.SqlServer.Tests.Source/Tables/TableIdentical.sql b/tests/Testing.Databases.SqlServer.Tests.Source/Tables/TableIdentical.sql index 95b8acc..5222feb 100644 --- a/tests/Testing.Databases.SqlServer.Tests.Source/Tables/TableIdentical.sql +++ b/tests/Testing.Databases.SqlServer.Tests.Source/Tables/TableIdentical.sql @@ -1,6 +1,6 @@ CREATE TABLE [dbo].[TableIdentical] ( - [Id] INT NOT NULL, + [Id] INT IDENTITY (4, 5) NOT NULL, [ForeignKeyId] INT NOT NULL CONSTRAINT DF_TableIdentical_ForeignKeyId DEFAULT (1 + 2 + 3), [IncludeColumn] INT NOT NULL, ) diff --git a/tests/Testing.Databases.SqlServer.Tests.Source/Tables/TableWithDifferentPrimaryKey.sql b/tests/Testing.Databases.SqlServer.Tests.Source/Tables/TableWithDifferentPrimaryKey.sql index 1dbe63a..e449ba6 100644 --- a/tests/Testing.Databases.SqlServer.Tests.Source/Tables/TableWithDifferentPrimaryKey.sql +++ b/tests/Testing.Databases.SqlServer.Tests.Source/Tables/TableWithDifferentPrimaryKey.sql @@ -1,6 +1,6 @@ CREATE TABLE [dbo].[TableWithDifferentPrimaryKey] ( - [Id] INT NOT NULL, + [Id] INT IDENTITY (10, 20) NOT NULL, CONSTRAINT [PK_TableWithDifferentPrimaryKey_Source] PRIMARY KEY CLUSTERED ([Id] ASC) ) diff --git a/tests/Testing.Databases.SqlServer.Tests.Source/Tables/TableWithNoPrimaryKey.sql b/tests/Testing.Databases.SqlServer.Tests.Source/Tables/TableWithNoPrimaryKey.sql new file mode 100644 index 0000000..f247444 --- /dev/null +++ b/tests/Testing.Databases.SqlServer.Tests.Source/Tables/TableWithNoPrimaryKey.sql @@ -0,0 +1,4 @@ +CREATE TABLE [dbo].[TableWithNoPrimaryKey] +( + [Id] INT IDENTITY (10, 20) NOT NULL, +) diff --git a/tests/Testing.Databases.SqlServer.Tests.Source/Tables/UniqueConstraints/UniqueConstraintDifferenceMissingInTarget.sql b/tests/Testing.Databases.SqlServer.Tests.Source/Tables/UniqueConstraints/UniqueConstraintDifferenceMissingInTarget.sql new file mode 100644 index 0000000..955a60c --- /dev/null +++ b/tests/Testing.Databases.SqlServer.Tests.Source/Tables/UniqueConstraints/UniqueConstraintDifferenceMissingInTarget.sql @@ -0,0 +1,3 @@ +ALTER TABLE [dbo].[TableDifference] + ADD CONSTRAINT [UniqueConstraintDifferenceMissingInTarget] + UNIQUE NONCLUSTERED ([Scale]) diff --git a/tests/Testing.Databases.SqlServer.Tests.Source/Testing.Databases.SqlServer.Tests.Source.sqlproj b/tests/Testing.Databases.SqlServer.Tests.Source/Testing.Databases.SqlServer.Tests.Source.sqlproj index b17888a..60bd7b0 100644 --- a/tests/Testing.Databases.SqlServer.Tests.Source/Testing.Databases.SqlServer.Tests.Source.sqlproj +++ b/tests/Testing.Databases.SqlServer.Tests.Source/Testing.Databases.SqlServer.Tests.Source.sqlproj @@ -102,5 +102,7 @@ + + \ No newline at end of file diff --git a/tests/Testing.Databases.SqlServer.Tests.Target/Tables/TableWithDifferentPrimaryKey.sql b/tests/Testing.Databases.SqlServer.Tests.Target/Tables/TableWithDifferentPrimaryKey.sql index fdc64c8..796bc42 100644 --- a/tests/Testing.Databases.SqlServer.Tests.Target/Tables/TableWithDifferentPrimaryKey.sql +++ b/tests/Testing.Databases.SqlServer.Tests.Target/Tables/TableWithDifferentPrimaryKey.sql @@ -1,6 +1,6 @@ CREATE TABLE [dbo].[TableWithDifferentPrimaryKey] ( - [Id] INT NOT NULL, + [Id] INT IDENTITY (1, 2) NOT NULL, CONSTRAINT [PK_TableWithDifferentPrimaryKey_Target] PRIMARY KEY CLUSTERED ([Id] ASC) ) diff --git a/tests/Testing.Databases.SqlServer.Tests.Target/Tables/TableWithNoPrimaryKey.sql b/tests/Testing.Databases.SqlServer.Tests.Target/Tables/TableWithNoPrimaryKey.sql new file mode 100644 index 0000000..b540e5f --- /dev/null +++ b/tests/Testing.Databases.SqlServer.Tests.Target/Tables/TableWithNoPrimaryKey.sql @@ -0,0 +1,4 @@ +CREATE TABLE [dbo].[TableWithNoPrimaryKey] +( + [Id] INT IDENTITY (10, 30) NOT NULL, +) diff --git a/tests/Testing.Databases.SqlServer.Tests.Target/Testing.Databases.SqlServer.Tests.Target.sqlproj b/tests/Testing.Databases.SqlServer.Tests.Target/Testing.Databases.SqlServer.Tests.Target.sqlproj index 6c3b10a..d34fed2 100644 --- a/tests/Testing.Databases.SqlServer.Tests.Target/Testing.Databases.SqlServer.Tests.Target.sqlproj +++ b/tests/Testing.Databases.SqlServer.Tests.Target/Testing.Databases.SqlServer.Tests.Target.sqlproj @@ -116,5 +116,6 @@ + \ No newline at end of file diff --git a/tests/Testing.Databases.SqlServer.Tests/ObjectModel/SqlColumnIdentityTest.cs b/tests/Testing.Databases.SqlServer.Tests/ObjectModel/SqlColumnIdentityTest.cs new file mode 100644 index 0000000..edfa88a --- /dev/null +++ b/tests/Testing.Databases.SqlServer.Tests/ObjectModel/SqlColumnIdentityTest.cs @@ -0,0 +1,19 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) P.O.S Informatique. All rights reserved. +// +//----------------------------------------------------------------------- + +namespace PosInformatique.Testing.Databases.Tests +{ + public class SqlColumnIdentityTest + { + [Fact] + public void ToStringTest() + { + var column = new SqlColumnIdentity(1, 2); + + column.ToString().Should().Be("(Seed: 1, Increment: 2)"); + } + } +} \ No newline at end of file diff --git a/tests/Testing.Databases.SqlServer.Tests/SqlServerDatabaseComparerTest.CompareAsync.txt b/tests/Testing.Databases.SqlServer.Tests/SqlServerDatabaseComparerTest.CompareAsync.txt index f4378c9..80b106f 100644 --- a/tests/Testing.Databases.SqlServer.Tests/SqlServerDatabaseComparerTest.CompareAsync.txt +++ b/tests/Testing.Databases.SqlServer.Tests/SqlServerDatabaseComparerTest.CompareAsync.txt @@ -42,9 +42,9 @@ Source: 2 Target: 4 - Identity - * IsIdentity: - Source: True - Target: False + * Identity: + Source: (Seed: 2, Increment: 3) + Target: - Computed * Scale: Source: 2 @@ -164,8 +164,14 @@ * Position: Source: 1 Target: 2 + - UniqueConstraintDifferenceMissingInTarget (Missing in the target) - dbo.TableTarget (Missing in the source) - dbo.TableWithDifferentPrimaryKey + ------ Columns ------ + - Id + * Identity: + Source: (Seed: 10, Increment: 20) + Target: (Seed: 1, Increment: 2) ------ Indexes ------ - PK_TableWithDifferentPrimaryKey_Target (Missing in the source) - PK_TableWithDifferentPrimaryKey_Source (Missing in the target) @@ -174,6 +180,12 @@ * Name: Source: PK_TableWithDifferentPrimaryKey_Source Target: PK_TableWithDifferentPrimaryKey_Target +- dbo.TableWithNoPrimaryKey + ------ Columns ------ + - Id + * Identity: + Source: (Seed: 10, Increment: 20) + Target: (Seed: 10, Increment: 30) - dbo.TableSource (Missing in the target) ------ Stored procedures ------ - dbo.StoredProcedureDifference diff --git a/tests/Testing.Databases.SqlServer.Tests/SqlServerDatabaseComparerTest.cs b/tests/Testing.Databases.SqlServer.Tests/SqlServerDatabaseComparerTest.cs index 4924451..03eb07b 100644 --- a/tests/Testing.Databases.SqlServer.Tests/SqlServerDatabaseComparerTest.cs +++ b/tests/Testing.Databases.SqlServer.Tests/SqlServerDatabaseComparerTest.cs @@ -52,7 +52,7 @@ public async Task CompareAsync() differences.StoredProcedures[2].Target.Should().BeNull(); // Tables - differences.Tables.Should().HaveCount(4); + differences.Tables.Should().HaveCount(5); differences.Tables[0].Source.Name.Should().Be("TableDifference"); differences.Tables[0].Source.Schema.Should().Be("dbo"); @@ -84,7 +84,7 @@ public async Task CompareAsync() differences.Tables[0].Source.Columns[0].ComputedExpression.Should().BeNull(); differences.Tables[0].Source.Columns[0].DefaultConstraint.Should().BeNull(); differences.Tables[0].Source.Columns[0].IsComputed.Should().BeFalse(); - differences.Tables[0].Source.Columns[0].IsIdentity.Should().BeFalse(); + differences.Tables[0].Source.Columns[0].Identity.Should().BeNull(); differences.Tables[0].Source.Columns[0].IsNullable.Should().BeFalse(); differences.Tables[0].Source.Columns[0].MaxLength.Should().Be(4); differences.Tables[0].Source.Columns[0].Name.Should().Be("Type"); @@ -97,7 +97,7 @@ public async Task CompareAsync() differences.Tables[0].Source.Columns[1].ComputedExpression.Should().BeNull(); differences.Tables[0].Source.Columns[1].DefaultConstraint.Should().BeNull(); differences.Tables[0].Source.Columns[1].IsComputed.Should().BeFalse(); - differences.Tables[0].Source.Columns[1].IsIdentity.Should().BeFalse(); + differences.Tables[0].Source.Columns[1].Identity.Should().BeNull(); differences.Tables[0].Source.Columns[1].IsNullable.Should().BeTrue(); differences.Tables[0].Source.Columns[1].MaxLength.Should().Be(50); differences.Tables[0].Source.Columns[1].Name.Should().Be("Nullable"); @@ -110,7 +110,7 @@ public async Task CompareAsync() differences.Tables[0].Source.Columns[2].ComputedExpression.Should().BeNull(); differences.Tables[0].Source.Columns[2].DefaultConstraint.Should().BeNull(); differences.Tables[0].Source.Columns[2].IsComputed.Should().BeFalse(); - differences.Tables[0].Source.Columns[2].IsIdentity.Should().BeFalse(); + differences.Tables[0].Source.Columns[2].Identity.Should().BeNull(); differences.Tables[0].Source.Columns[2].IsNullable.Should().BeFalse(); differences.Tables[0].Source.Columns[2].MaxLength.Should().Be(50); differences.Tables[0].Source.Columns[2].Name.Should().Be("MaxLength"); @@ -123,7 +123,7 @@ public async Task CompareAsync() differences.Tables[0].Source.Columns[3].ComputedExpression.Should().BeNull(); differences.Tables[0].Source.Columns[3].DefaultConstraint.Should().BeNull(); differences.Tables[0].Source.Columns[3].IsComputed.Should().BeFalse(); - differences.Tables[0].Source.Columns[3].IsIdentity.Should().BeFalse(); + differences.Tables[0].Source.Columns[3].Identity.Should().BeNull(); differences.Tables[0].Source.Columns[3].IsNullable.Should().BeFalse(); differences.Tables[0].Source.Columns[3].MaxLength.Should().Be(9); differences.Tables[0].Source.Columns[3].Name.Should().Be("Precision"); @@ -136,7 +136,7 @@ public async Task CompareAsync() differences.Tables[0].Source.Columns[4].ComputedExpression.Should().BeNull(); differences.Tables[0].Source.Columns[4].DefaultConstraint.Should().BeNull(); differences.Tables[0].Source.Columns[4].IsComputed.Should().BeFalse(); - differences.Tables[0].Source.Columns[4].IsIdentity.Should().BeFalse(); + differences.Tables[0].Source.Columns[4].Identity.Should().BeNull(); differences.Tables[0].Source.Columns[4].IsNullable.Should().BeFalse(); differences.Tables[0].Source.Columns[4].MaxLength.Should().Be(9); differences.Tables[0].Source.Columns[4].Name.Should().Be("Scale"); @@ -149,7 +149,8 @@ public async Task CompareAsync() differences.Tables[0].Source.Columns[5].ComputedExpression.Should().BeNull(); differences.Tables[0].Source.Columns[5].DefaultConstraint.Should().BeNull(); differences.Tables[0].Source.Columns[5].IsComputed.Should().BeFalse(); - differences.Tables[0].Source.Columns[5].IsIdentity.Should().BeTrue(); + differences.Tables[0].Source.Columns[5].Identity.Increment.Should().Be(3); + differences.Tables[0].Source.Columns[5].Identity.Seed.Should().Be(2); differences.Tables[0].Source.Columns[5].IsNullable.Should().BeFalse(); differences.Tables[0].Source.Columns[5].MaxLength.Should().Be(4); differences.Tables[0].Source.Columns[5].Name.Should().Be("Identity"); @@ -162,7 +163,7 @@ public async Task CompareAsync() differences.Tables[0].Source.Columns[6].ComputedExpression.Should().BeNull(); differences.Tables[0].Source.Columns[6].DefaultConstraint.Should().BeNull(); differences.Tables[0].Source.Columns[6].IsComputed.Should().BeFalse(); - differences.Tables[0].Source.Columns[6].IsIdentity.Should().BeFalse(); + differences.Tables[0].Source.Columns[6].Identity.Should().BeNull(); differences.Tables[0].Source.Columns[6].IsNullable.Should().BeTrue(); differences.Tables[0].Source.Columns[6].MaxLength.Should().Be(4); differences.Tables[0].Source.Columns[6].Name.Should().Be("ForeignKeyId"); @@ -175,7 +176,7 @@ public async Task CompareAsync() differences.Tables[0].Source.Columns[7].ComputedExpression.Should().Be("([Scale]+[Precision])"); differences.Tables[0].Source.Columns[7].DefaultConstraint.Should().BeNull(); differences.Tables[0].Source.Columns[7].IsComputed.Should().BeTrue(); - differences.Tables[0].Source.Columns[7].IsIdentity.Should().BeFalse(); + differences.Tables[0].Source.Columns[7].Identity.Should().BeNull(); differences.Tables[0].Source.Columns[7].IsNullable.Should().BeTrue(); differences.Tables[0].Source.Columns[7].MaxLength.Should().Be(9); differences.Tables[0].Source.Columns[7].Name.Should().Be("Computed"); @@ -188,7 +189,7 @@ public async Task CompareAsync() differences.Tables[0].Source.Columns[8].ComputedExpression.Should().BeNull(); differences.Tables[0].Source.Columns[8].DefaultConstraint.Should().BeNull(); differences.Tables[0].Source.Columns[8].IsComputed.Should().BeFalse(); - differences.Tables[0].Source.Columns[8].IsIdentity.Should().BeFalse(); + differences.Tables[0].Source.Columns[8].Identity.Should().BeNull(); differences.Tables[0].Source.Columns[8].IsNullable.Should().BeFalse(); differences.Tables[0].Source.Columns[8].MaxLength.Should().Be(4); differences.Tables[0].Source.Columns[8].Name.Should().Be("SourceColumn"); @@ -201,7 +202,7 @@ public async Task CompareAsync() differences.Tables[0].Source.Columns[9].ComputedExpression.Should().BeNull(); differences.Tables[0].Source.Columns[9].DefaultConstraint.Should().BeNull(); differences.Tables[0].Source.Columns[9].IsComputed.Should().BeFalse(); - differences.Tables[0].Source.Columns[9].IsIdentity.Should().BeFalse(); + differences.Tables[0].Source.Columns[9].Identity.Should().BeNull(); differences.Tables[0].Source.Columns[9].IsNullable.Should().BeFalse(); differences.Tables[0].Source.Columns[9].MaxLength.Should().Be(4); differences.Tables[0].Source.Columns[9].Name.Should().Be("IdenticalColumn"); @@ -215,7 +216,7 @@ public async Task CompareAsync() differences.Tables[0].Source.Columns[10].DefaultConstraint.Expression.Should().Be("('Source expression')"); differences.Tables[0].Source.Columns[10].DefaultConstraint.Name.Should().Be("DF_TableDifference_ColumnWithDefaultConstraint"); differences.Tables[0].Source.Columns[10].IsComputed.Should().BeFalse(); - differences.Tables[0].Source.Columns[10].IsIdentity.Should().BeFalse(); + differences.Tables[0].Source.Columns[10].Identity.Should().BeNull(); differences.Tables[0].Source.Columns[10].IsNullable.Should().BeFalse(); differences.Tables[0].Source.Columns[10].MaxLength.Should().Be(20); differences.Tables[0].Source.Columns[10].Name.Should().Be("ColumnWithDefaultConstraint"); @@ -229,7 +230,7 @@ public async Task CompareAsync() differences.Tables[0].Source.Columns[11].DefaultConstraint.Expression.Should().Be("('Default value')"); differences.Tables[0].Source.Columns[11].DefaultConstraint.Name.Should().Be("DF_TableDifference_ColumnWithMissingDefaultConstraint"); differences.Tables[0].Source.Columns[11].IsComputed.Should().BeFalse(); - differences.Tables[0].Source.Columns[11].IsIdentity.Should().BeFalse(); + differences.Tables[0].Source.Columns[11].Identity.Should().BeNull(); differences.Tables[0].Source.Columns[11].IsNullable.Should().BeFalse(); differences.Tables[0].Source.Columns[11].MaxLength.Should().Be(20); differences.Tables[0].Source.Columns[11].Name.Should().Be("ColumnWithMissingDefaultConstraint"); @@ -243,7 +244,7 @@ public async Task CompareAsync() differences.Tables[0].Source.Columns[12].DefaultConstraint.Expression.Should().Be("('Same expression')"); differences.Tables[0].Source.Columns[12].DefaultConstraint.Name.Should().Be("DF_TableDifference_ColumnWithOtherDefaultConstraintName"); differences.Tables[0].Source.Columns[12].IsComputed.Should().BeFalse(); - differences.Tables[0].Source.Columns[12].IsIdentity.Should().BeFalse(); + differences.Tables[0].Source.Columns[12].Identity.Should().BeNull(); differences.Tables[0].Source.Columns[12].IsNullable.Should().BeFalse(); differences.Tables[0].Source.Columns[12].MaxLength.Should().Be(20); differences.Tables[0].Source.Columns[12].Name.Should().Be("ColumnWithOtherDefaultConstraintName"); @@ -261,7 +262,7 @@ public async Task CompareAsync() differences.Tables[0].Target.Columns[0].ComputedExpression.Should().BeNull(); differences.Tables[0].Target.Columns[0].DefaultConstraint.Should().BeNull(); differences.Tables[0].Target.Columns[0].IsComputed.Should().BeFalse(); - differences.Tables[0].Target.Columns[0].IsIdentity.Should().BeFalse(); + differences.Tables[0].Target.Columns[0].Identity.Should().BeNull(); differences.Tables[0].Target.Columns[0].IsNullable.Should().BeFalse(); differences.Tables[0].Target.Columns[0].MaxLength.Should().Be(50); differences.Tables[0].Target.Columns[0].Name.Should().Be("Type"); @@ -274,7 +275,7 @@ public async Task CompareAsync() differences.Tables[0].Target.Columns[1].ComputedExpression.Should().BeNull(); differences.Tables[0].Target.Columns[1].DefaultConstraint.Should().BeNull(); differences.Tables[0].Target.Columns[1].IsComputed.Should().BeFalse(); - differences.Tables[0].Target.Columns[1].IsIdentity.Should().BeFalse(); + differences.Tables[0].Target.Columns[1].Identity.Should().BeNull(); differences.Tables[0].Target.Columns[1].IsNullable.Should().BeFalse(); differences.Tables[0].Target.Columns[1].MaxLength.Should().Be(50); differences.Tables[0].Target.Columns[1].Name.Should().Be("Nullable"); @@ -287,7 +288,7 @@ public async Task CompareAsync() differences.Tables[0].Target.Columns[2].ComputedExpression.Should().BeNull(); differences.Tables[0].Target.Columns[2].DefaultConstraint.Should().BeNull(); differences.Tables[0].Target.Columns[2].IsComputed.Should().BeFalse(); - differences.Tables[0].Target.Columns[2].IsIdentity.Should().BeFalse(); + differences.Tables[0].Target.Columns[2].Identity.Should().BeNull(); differences.Tables[0].Target.Columns[2].IsNullable.Should().BeFalse(); differences.Tables[0].Target.Columns[2].MaxLength.Should().Be(5); differences.Tables[0].Target.Columns[2].Name.Should().Be("Precision"); @@ -300,7 +301,7 @@ public async Task CompareAsync() differences.Tables[0].Target.Columns[3].ComputedExpression.Should().BeNull(); differences.Tables[0].Target.Columns[3].DefaultConstraint.Should().BeNull(); differences.Tables[0].Target.Columns[3].IsComputed.Should().BeFalse(); - differences.Tables[0].Target.Columns[3].IsIdentity.Should().BeFalse(); + differences.Tables[0].Target.Columns[3].Identity.Should().BeNull(); differences.Tables[0].Target.Columns[3].IsNullable.Should().BeFalse(); differences.Tables[0].Target.Columns[3].MaxLength.Should().Be(20); differences.Tables[0].Target.Columns[3].Name.Should().Be("MaxLength"); @@ -313,7 +314,7 @@ public async Task CompareAsync() differences.Tables[0].Target.Columns[4].ComputedExpression.Should().BeNull(); differences.Tables[0].Target.Columns[4].DefaultConstraint.Should().BeNull(); differences.Tables[0].Target.Columns[4].IsComputed.Should().BeFalse(); - differences.Tables[0].Target.Columns[4].IsIdentity.Should().BeFalse(); + differences.Tables[0].Target.Columns[4].Identity.Should().BeNull(); differences.Tables[0].Target.Columns[4].IsNullable.Should().BeFalse(); differences.Tables[0].Target.Columns[4].MaxLength.Should().Be(9); differences.Tables[0].Target.Columns[4].Name.Should().Be("Scale"); @@ -326,7 +327,7 @@ public async Task CompareAsync() differences.Tables[0].Target.Columns[5].ComputedExpression.Should().BeNull(); differences.Tables[0].Target.Columns[5].DefaultConstraint.Should().BeNull(); differences.Tables[0].Target.Columns[5].IsComputed.Should().BeFalse(); - differences.Tables[0].Target.Columns[5].IsIdentity.Should().BeFalse(); + differences.Tables[0].Target.Columns[5].Identity.Should().BeNull(); differences.Tables[0].Target.Columns[5].IsNullable.Should().BeFalse(); differences.Tables[0].Target.Columns[5].MaxLength.Should().Be(4); differences.Tables[0].Target.Columns[5].Name.Should().Be("Identity"); @@ -339,7 +340,7 @@ public async Task CompareAsync() differences.Tables[0].Target.Columns[6].ComputedExpression.Should().BeNull(); differences.Tables[0].Target.Columns[6].DefaultConstraint.Should().BeNull(); differences.Tables[0].Target.Columns[6].IsComputed.Should().BeFalse(); - differences.Tables[0].Target.Columns[6].IsIdentity.Should().BeFalse(); + differences.Tables[0].Target.Columns[6].Identity.Should().BeNull(); differences.Tables[0].Target.Columns[6].IsNullable.Should().BeTrue(); differences.Tables[0].Target.Columns[6].MaxLength.Should().Be(4); differences.Tables[0].Target.Columns[6].Name.Should().Be("ForeignKeyId"); @@ -352,7 +353,7 @@ public async Task CompareAsync() differences.Tables[0].Target.Columns[7].ComputedExpression.Should().Be("([Scale]-[Precision])"); differences.Tables[0].Target.Columns[7].DefaultConstraint.Should().BeNull(); differences.Tables[0].Target.Columns[7].IsComputed.Should().BeTrue(); - differences.Tables[0].Target.Columns[7].IsIdentity.Should().BeFalse(); + differences.Tables[0].Target.Columns[7].Identity.Should().BeNull(); differences.Tables[0].Target.Columns[7].IsNullable.Should().BeTrue(); differences.Tables[0].Target.Columns[7].MaxLength.Should().Be(9); differences.Tables[0].Target.Columns[7].Name.Should().Be("Computed"); @@ -365,7 +366,7 @@ public async Task CompareAsync() differences.Tables[0].Target.Columns[8].ComputedExpression.Should().BeNull(); differences.Tables[0].Target.Columns[8].DefaultConstraint.Should().BeNull(); differences.Tables[0].Target.Columns[8].IsComputed.Should().BeFalse(); - differences.Tables[0].Target.Columns[8].IsIdentity.Should().BeFalse(); + differences.Tables[0].Target.Columns[8].Identity.Should().BeNull(); differences.Tables[0].Target.Columns[8].IsNullable.Should().BeFalse(); differences.Tables[0].Target.Columns[8].MaxLength.Should().Be(4); differences.Tables[0].Target.Columns[8].Name.Should().Be("TargetColumn"); @@ -378,7 +379,7 @@ public async Task CompareAsync() differences.Tables[0].Target.Columns[9].ComputedExpression.Should().BeNull(); differences.Tables[0].Target.Columns[9].DefaultConstraint.Should().BeNull(); differences.Tables[0].Target.Columns[9].IsComputed.Should().BeFalse(); - differences.Tables[0].Target.Columns[9].IsIdentity.Should().BeFalse(); + differences.Tables[0].Target.Columns[9].Identity.Should().BeNull(); differences.Tables[0].Target.Columns[9].IsNullable.Should().BeFalse(); differences.Tables[0].Target.Columns[9].MaxLength.Should().Be(4); differences.Tables[0].Target.Columns[9].Name.Should().Be("IdenticalColumn"); @@ -392,7 +393,7 @@ public async Task CompareAsync() differences.Tables[0].Target.Columns[10].DefaultConstraint.Expression.Should().Be("('Target expression')"); differences.Tables[0].Target.Columns[10].DefaultConstraint.Name.Should().Be("DF_TableDifference_ColumnWithDefaultConstraint"); differences.Tables[0].Target.Columns[10].IsComputed.Should().BeFalse(); - differences.Tables[0].Target.Columns[10].IsIdentity.Should().BeFalse(); + differences.Tables[0].Target.Columns[10].Identity.Should().BeNull(); differences.Tables[0].Target.Columns[10].IsNullable.Should().BeFalse(); differences.Tables[0].Target.Columns[10].MaxLength.Should().Be(20); differences.Tables[0].Target.Columns[10].Name.Should().Be("ColumnWithDefaultConstraint"); @@ -405,7 +406,7 @@ public async Task CompareAsync() differences.Tables[0].Target.Columns[11].ComputedExpression.Should().BeNull(); differences.Tables[0].Target.Columns[11].DefaultConstraint.Should().BeNull(); differences.Tables[0].Target.Columns[11].IsComputed.Should().BeFalse(); - differences.Tables[0].Target.Columns[11].IsIdentity.Should().BeFalse(); + differences.Tables[0].Target.Columns[11].Identity.Should().BeNull(); differences.Tables[0].Target.Columns[11].IsNullable.Should().BeFalse(); differences.Tables[0].Target.Columns[11].MaxLength.Should().Be(20); differences.Tables[0].Target.Columns[11].Name.Should().Be("ColumnWithMissingDefaultConstraint"); @@ -419,7 +420,7 @@ public async Task CompareAsync() differences.Tables[0].Target.Columns[12].DefaultConstraint.Expression.Should().Be("('Same expression')"); differences.Tables[0].Target.Columns[12].DefaultConstraint.Name.Should().Be("DF_TableDifference_WrongName"); differences.Tables[0].Target.Columns[12].IsComputed.Should().BeFalse(); - differences.Tables[0].Target.Columns[12].IsIdentity.Should().BeFalse(); + differences.Tables[0].Target.Columns[12].Identity.Should().BeNull(); differences.Tables[0].Target.Columns[12].IsNullable.Should().BeFalse(); differences.Tables[0].Target.Columns[12].MaxLength.Should().Be(20); differences.Tables[0].Target.Columns[12].Name.Should().Be("ColumnWithOtherDefaultConstraintName"); @@ -718,7 +719,7 @@ public async Task CompareAsync() differences.Tables[0].Triggers[0].Type.Should().Be(SqlObjectDifferenceType.Different); // Tables / Unique constraints - differences.Tables[0].Source.UniqueConstraints.Should().HaveCount(1); + differences.Tables[0].Source.UniqueConstraints.Should().HaveCount(2); differences.Tables[0].Source.UniqueConstraints[0].Columns.Should().HaveCount(2); differences.Tables[0].Source.UniqueConstraints[0].Columns[0].Name.Should().Be("Type"); differences.Tables[0].Source.UniqueConstraints[0].Columns[0].Position.Should().Be(1); @@ -726,6 +727,11 @@ public async Task CompareAsync() differences.Tables[0].Source.UniqueConstraints[0].Columns[1].Position.Should().Be(2); differences.Tables[0].Source.UniqueConstraints[0].Name.Should().Be("UniqueConstraintDifference"); differences.Tables[0].Source.UniqueConstraints[0].Type.Should().Be("CLUSTERED"); + differences.Tables[0].Source.UniqueConstraints[1].Columns.Should().HaveCount(1); + differences.Tables[0].Source.UniqueConstraints[1].Columns[0].Name.Should().Be("Scale"); + differences.Tables[0].Source.UniqueConstraints[1].Columns[0].Position.Should().Be(1); + differences.Tables[0].Source.UniqueConstraints[1].Name.Should().Be("UniqueConstraintDifferenceMissingInTarget"); + differences.Tables[0].Source.UniqueConstraints[1].Type.Should().Be("NONCLUSTERED"); differences.Tables[0].Target.UniqueConstraints.Should().HaveCount(1); differences.Tables[0].Target.UniqueConstraints[0].Columns.Should().HaveCount(2); @@ -736,7 +742,7 @@ public async Task CompareAsync() differences.Tables[0].Target.UniqueConstraints[0].Name.Should().Be("UniqueConstraintDifference"); differences.Tables[0].Target.UniqueConstraints[0].Type.Should().Be("NONCLUSTERED"); - differences.Tables[0].UniqueConstraints.Should().HaveCount(1); + differences.Tables[0].UniqueConstraints.Should().HaveCount(2); differences.Tables[0].UniqueConstraints[0].Properties.Should().HaveCount(1); differences.Tables[0].UniqueConstraints[0].Properties[0].Name.Should().Be("Type"); differences.Tables[0].UniqueConstraints[0].Properties[0].Source.Should().Be("CLUSTERED"); @@ -744,6 +750,10 @@ public async Task CompareAsync() differences.Tables[0].UniqueConstraints[0].Source.Should().BeSameAs(differences.Tables[0].Source.UniqueConstraints[0]); differences.Tables[0].UniqueConstraints[0].Target.Should().BeSameAs(differences.Tables[0].Target.UniqueConstraints[0]); differences.Tables[0].UniqueConstraints[0].Type.Should().Be(SqlObjectDifferenceType.Different); + differences.Tables[0].UniqueConstraints[1].Properties.Should().BeEmpty(); + differences.Tables[0].UniqueConstraints[1].Source.Should().BeSameAs(differences.Tables[0].Source.UniqueConstraints[1]); + differences.Tables[0].UniqueConstraints[1].Target.Should().BeNull(); + differences.Tables[0].UniqueConstraints[1].Type.Should().Be(SqlObjectDifferenceType.MissingInTarget); // Missing tables differences.Tables[1].Columns.Should().BeEmpty(); @@ -758,7 +768,7 @@ public async Task CompareAsync() differences.Tables[1].Target.Columns[0].CollationName.Should().BeNull(); differences.Tables[1].Target.Columns[0].ComputedExpression.Should().BeNull(); differences.Tables[1].Target.Columns[0].IsComputed.Should().BeFalse(); - differences.Tables[1].Target.Columns[0].IsIdentity.Should().BeFalse(); + differences.Tables[1].Target.Columns[0].Identity.Should().BeNull(); differences.Tables[1].Target.Columns[0].IsNullable.Should().BeFalse(); differences.Tables[1].Target.Columns[0].MaxLength.Should().Be(4); differences.Tables[1].Target.Columns[0].Name.Should().Be("Id"); @@ -769,7 +779,7 @@ public async Task CompareAsync() differences.Tables[1].Target.Columns[1].CollationName.Should().Be("SQL_Latin1_General_CP1_CI_AS"); differences.Tables[1].Target.Columns[1].ComputedExpression.Should().BeNull(); differences.Tables[1].Target.Columns[1].IsComputed.Should().BeFalse(); - differences.Tables[1].Target.Columns[1].IsIdentity.Should().BeFalse(); + differences.Tables[1].Target.Columns[1].Identity.Should().BeNull(); differences.Tables[1].Target.Columns[1].IsNullable.Should().BeTrue(); differences.Tables[1].Target.Columns[1].MaxLength.Should().Be(50); differences.Tables[1].Target.Columns[1].Name.Should().Be("TargetName"); @@ -780,7 +790,7 @@ public async Task CompareAsync() differences.Tables[1].Target.Columns[2].CollationName.Should().BeNull(); differences.Tables[1].Target.Columns[2].ComputedExpression.Should().BeNull(); differences.Tables[1].Target.Columns[2].IsComputed.Should().BeFalse(); - differences.Tables[1].Target.Columns[2].IsIdentity.Should().BeFalse(); + differences.Tables[1].Target.Columns[2].Identity.Should().BeNull(); differences.Tables[1].Target.Columns[2].IsNullable.Should().BeFalse(); differences.Tables[1].Target.Columns[2].MaxLength.Should().Be(4); differences.Tables[1].Target.Columns[2].Name.Should().Be("TargetForeignKeyId"); @@ -828,7 +838,11 @@ public async Task CompareAsync() differences.Tables[1].Triggers.Should().BeEmpty(); differences.Tables[1].Type.Should().Be(SqlObjectDifferenceType.MissingInSource); - differences.Tables[2].Columns.Should().BeEmpty(); + differences.Tables[2].Columns.Should().HaveCount(1); + differences.Tables[2].Columns[0].Properties.Should().HaveCount(1); + differences.Tables[2].Columns[0].Properties[0].Name.Should().Be("Identity"); + differences.Tables[2].Columns[0].Properties[0].Source.Should().BeSameAs(differences.Tables[2].Source.Columns[0].Identity); + differences.Tables[2].Columns[0].Properties[0].Target.Should().BeSameAs(differences.Tables[2].Target.Columns[0].Identity); differences.Tables[2].Indexes.Should().HaveCount(2); differences.Tables[2].Indexes[0].Columns.Should().BeEmpty(); differences.Tables[2].Indexes[0].IncludedColumns.Should().BeEmpty(); @@ -854,7 +868,8 @@ public async Task CompareAsync() differences.Tables[2].Source.Columns[0].CollationName.Should().BeNull(); differences.Tables[2].Source.Columns[0].ComputedExpression.Should().BeNull(); differences.Tables[2].Source.Columns[0].IsComputed.Should().BeFalse(); - differences.Tables[2].Source.Columns[0].IsIdentity.Should().BeFalse(); + differences.Tables[2].Source.Columns[0].Identity.Increment.Should().Be(20); + differences.Tables[2].Source.Columns[0].Identity.Seed.Should().Be(10); differences.Tables[2].Source.Columns[0].IsNullable.Should().BeFalse(); differences.Tables[2].Source.Columns[0].MaxLength.Should().Be(4); differences.Tables[2].Source.Columns[0].Name.Should().Be("Id"); @@ -882,7 +897,8 @@ public async Task CompareAsync() differences.Tables[2].Target.Columns[0].CollationName.Should().BeNull(); differences.Tables[2].Target.Columns[0].ComputedExpression.Should().BeNull(); differences.Tables[2].Target.Columns[0].IsComputed.Should().BeFalse(); - differences.Tables[2].Target.Columns[0].IsIdentity.Should().BeFalse(); + differences.Tables[2].Target.Columns[0].Identity.Increment.Should().Be(2); + differences.Tables[2].Target.Columns[0].Identity.Seed.Should().Be(1); differences.Tables[2].Target.Columns[0].IsNullable.Should().BeFalse(); differences.Tables[2].Target.Columns[0].MaxLength.Should().Be(4); differences.Tables[2].Target.Columns[0].Name.Should().Be("Id"); @@ -908,18 +924,21 @@ public async Task CompareAsync() differences.Tables[2].Triggers.Should().BeEmpty(); differences.Tables[2].Type.Should().Be(SqlObjectDifferenceType.Different); - differences.Tables[3].Columns.Should().BeEmpty(); + differences.Tables[3].Columns.Should().HaveCount(1); + differences.Tables[3].Columns[0].Properties.Should().HaveCount(1); + differences.Tables[3].Columns[0].Properties[0].Name.Should().Be("Identity"); + differences.Tables[3].Columns[0].Properties[0].Source.Should().BeSameAs(differences.Tables[3].Source.Columns[0].Identity); + differences.Tables[3].Columns[0].Properties[0].Target.Should().BeSameAs(differences.Tables[3].Target.Columns[0].Identity); differences.Tables[3].Indexes.Should().BeEmpty(); differences.Tables[3].PrimaryKey.Should().BeNull(); differences.Tables[3].UniqueConstraints.Should().BeEmpty(); - differences.Tables[3].Source.CheckConstraints.Should().HaveCount(1); - differences.Tables[3].Source.CheckConstraints[0].Name.Should().Be("CheckConstraintSource"); - differences.Tables[3].Source.CheckConstraints[0].Code.Should().Be("([Id]>(0))"); - differences.Tables[3].Source.Columns.Should().HaveCount(3); + differences.Tables[3].Source.CheckConstraints.Should().BeEmpty(); + differences.Tables[3].Source.Columns.Should().HaveCount(1); differences.Tables[3].Source.Columns[0].CollationName.Should().BeNull(); differences.Tables[3].Source.Columns[0].ComputedExpression.Should().BeNull(); differences.Tables[3].Source.Columns[0].IsComputed.Should().BeFalse(); - differences.Tables[3].Source.Columns[0].IsIdentity.Should().BeFalse(); + differences.Tables[3].Source.Columns[0].Identity.Increment.Should().Be(20); + differences.Tables[3].Source.Columns[0].Identity.Seed.Should().Be(10); differences.Tables[3].Source.Columns[0].IsNullable.Should().BeFalse(); differences.Tables[3].Source.Columns[0].MaxLength.Should().Be(4); differences.Tables[3].Source.Columns[0].Name.Should().Be("Id"); @@ -927,46 +946,118 @@ public async Task CompareAsync() differences.Tables[3].Source.Columns[0].Precision.Should().Be(10); differences.Tables[3].Source.Columns[0].Scale.Should().Be(0); differences.Tables[3].Source.Columns[0].TypeName.Should().Be("int"); - differences.Tables[3].Source.Indexes.Should().HaveCount(2); - differences.Tables[3].Source.Indexes[0].Columns.Should().HaveCount(1); - differences.Tables[3].Source.Indexes[0].Columns[0].Name.Should().Be("SourceName"); - differences.Tables[3].Source.Indexes[0].Columns[0].Position.Should().Be(1); - differences.Tables[3].Source.Indexes[0].Filter.Should().Be("([SourceName]='')"); - differences.Tables[3].Source.Indexes[0].IncludedColumns.Should().HaveCount(1); - differences.Tables[3].Source.Indexes[0].IncludedColumns[0].Name.Should().Be("SourceForeignKeyId"); - differences.Tables[3].Source.Indexes[0].IncludedColumns[0].Position.Should().Be(1); - differences.Tables[3].Source.Indexes[0].IsUnique.Should().BeFalse(); - differences.Tables[3].Source.Indexes[0].Name.Should().Be("IndexSource"); - differences.Tables[3].Source.Indexes[1].Columns.Should().HaveCount(1); - differences.Tables[3].Source.Indexes[1].Columns[0].Name.Should().Be("Id"); - differences.Tables[3].Source.Indexes[1].Columns[0].Position.Should().Be(1); - differences.Tables[3].Source.Indexes[1].Filter.Should().BeNull(); - differences.Tables[3].Source.Indexes[1].IncludedColumns.Should().HaveCount(0); - differences.Tables[3].Source.ForeignKeys.Should().HaveCount(1); - differences.Tables[3].Source.ForeignKeys[0].Columns.Should().HaveCount(1); - differences.Tables[3].Source.ForeignKeys[0].Columns[0].Name.Should().Be("SourceForeignKeyId"); - differences.Tables[3].Source.ForeignKeys[0].Columns[0].Position.Should().Be(1); - differences.Tables[3].Source.ForeignKeys[0].DeleteAction.Should().Be("NO_ACTION"); - differences.Tables[3].Source.ForeignKeys[0].Name.Should().Be("ForeignKeySource"); - differences.Tables[3].Source.ForeignKeys[0].ReferencedTable.Should().Be("ReferencedTable"); - differences.Tables[3].Source.ForeignKeys[0].UpdateAction.Should().Be("NO_ACTION"); - differences.Tables[3].Source.Name.Should().Be("TableSource"); + differences.Tables[3].Source.Indexes.Should().BeEmpty(); + differences.Tables[3].Source.ForeignKeys.Should().BeEmpty(); + differences.Tables[3].Source.Name.Should().Be("TableWithNoPrimaryKey"); differences.Tables[3].Source.Schema.Should().Be("dbo"); - differences.Tables[3].Source.PrimaryKey.Name.Should().Be("PrimaryKeySource"); - differences.Tables[3].Source.PrimaryKey.Type.Should().Be("CLUSTERED"); - differences.Tables[3].Source.Triggers.Should().HaveCount(1); - differences.Tables[3].Source.Triggers[0].Name.Should().Be("TriggerSource"); - differences.Tables[3].Source.Triggers[0].Code.Should().Be("CREATE TRIGGER [TriggerSource]\r\n\tON [dbo].[TableSource]\r\n\tFOR DELETE, INSERT, UPDATE\r\n\tAS\r\n\tBEGIN\r\n\t\tSET NOCOUNT ON\r\n\tEND"); - differences.Tables[3].Source.Triggers[0].IsInsteadOfTrigger.Should().BeFalse(); - differences.Tables[3].Source.UniqueConstraints.Should().HaveCount(1); - differences.Tables[3].Source.UniqueConstraints[0].Columns.Should().HaveCount(1); - differences.Tables[3].Source.UniqueConstraints[0].Columns[0].Name.Should().Be("Id"); - differences.Tables[3].Source.UniqueConstraints[0].Columns[0].Position.Should().Be(1); - differences.Tables[3].Source.UniqueConstraints[0].Name.Should().Be("UniqueConstraintSource"); - differences.Tables[3].Source.UniqueConstraints[0].Type.Should().Be("NONCLUSTERED"); - differences.Tables[3].Target.Should().BeNull(); + differences.Tables[3].Source.PrimaryKey.Should().BeNull(); + differences.Tables[3].Source.Triggers.Should().BeEmpty(); + differences.Tables[3].Source.UniqueConstraints.Should().BeEmpty(); + differences.Tables[3].Target.CheckConstraints.Should().BeEmpty(); + differences.Tables[3].Target.Columns.Should().HaveCount(1); + differences.Tables[3].Target.Columns[0].CollationName.Should().BeNull(); + differences.Tables[3].Target.Columns[0].ComputedExpression.Should().BeNull(); + differences.Tables[3].Target.Columns[0].IsComputed.Should().BeFalse(); + differences.Tables[3].Target.Columns[0].Identity.Increment.Should().Be(30); + differences.Tables[3].Target.Columns[0].Identity.Seed.Should().Be(10); + differences.Tables[3].Target.Columns[0].IsNullable.Should().BeFalse(); + differences.Tables[3].Target.Columns[0].MaxLength.Should().Be(4); + differences.Tables[3].Target.Columns[0].Name.Should().Be("Id"); + differences.Tables[3].Target.Columns[0].Position.Should().Be(1); + differences.Tables[3].Target.Columns[0].Precision.Should().Be(10); + differences.Tables[3].Target.Columns[0].Scale.Should().Be(0); + differences.Tables[3].Target.Columns[0].TypeName.Should().Be("int"); + differences.Tables[3].Target.Indexes.Should().BeEmpty(); + differences.Tables[3].Target.ForeignKeys.Should().BeEmpty(); + differences.Tables[3].Target.Name.Should().Be("TableWithNoPrimaryKey"); + differences.Tables[3].Target.Schema.Should().Be("dbo"); + differences.Tables[3].Target.PrimaryKey.Should().BeNull(); + differences.Tables[3].Target.Triggers.Should().BeEmpty(); + differences.Tables[3].Target.UniqueConstraints.Should().BeEmpty(); differences.Tables[3].Triggers.Should().BeEmpty(); - differences.Tables[3].Type.Should().Be(SqlObjectDifferenceType.MissingInTarget); + differences.Tables[3].Type.Should().Be(SqlObjectDifferenceType.Different); + + differences.Tables[4].Columns.Should().BeEmpty(); + differences.Tables[4].Indexes.Should().BeEmpty(); + differences.Tables[4].PrimaryKey.Should().BeNull(); + differences.Tables[4].UniqueConstraints.Should().BeEmpty(); + differences.Tables[4].Source.CheckConstraints.Should().HaveCount(1); + differences.Tables[4].Source.CheckConstraints[0].Name.Should().Be("CheckConstraintSource"); + differences.Tables[4].Source.CheckConstraints[0].Code.Should().Be("([Id]>(0))"); + differences.Tables[4].Source.Columns.Should().HaveCount(3); + differences.Tables[4].Source.Columns[0].CollationName.Should().BeNull(); + differences.Tables[4].Source.Columns[0].ComputedExpression.Should().BeNull(); + differences.Tables[4].Source.Columns[0].IsComputed.Should().BeFalse(); + differences.Tables[4].Source.Columns[0].Identity.Should().BeNull(); + differences.Tables[4].Source.Columns[0].IsNullable.Should().BeFalse(); + differences.Tables[4].Source.Columns[0].MaxLength.Should().Be(4); + differences.Tables[4].Source.Columns[0].Name.Should().Be("Id"); + differences.Tables[4].Source.Columns[0].Position.Should().Be(1); + differences.Tables[4].Source.Columns[0].Precision.Should().Be(10); + differences.Tables[4].Source.Columns[0].Scale.Should().Be(0); + differences.Tables[4].Source.Columns[0].TypeName.Should().Be("int"); + differences.Tables[4].Source.Columns[1].CollationName.Should().Be("SQL_Latin1_General_CP1_CI_AS"); + differences.Tables[4].Source.Columns[1].ComputedExpression.Should().BeNull(); + differences.Tables[4].Source.Columns[1].IsComputed.Should().BeFalse(); + differences.Tables[4].Source.Columns[1].Identity.Should().BeNull(); + differences.Tables[4].Source.Columns[1].IsNullable.Should().BeTrue(); + differences.Tables[4].Source.Columns[1].MaxLength.Should().Be(50); + differences.Tables[4].Source.Columns[1].Name.Should().Be("SourceName"); + differences.Tables[4].Source.Columns[1].Position.Should().Be(2); + differences.Tables[4].Source.Columns[1].Precision.Should().Be(0); + differences.Tables[4].Source.Columns[1].Scale.Should().Be(0); + differences.Tables[4].Source.Columns[1].TypeName.Should().Be("varchar"); + differences.Tables[4].Source.Columns[2].CollationName.Should().BeNull(); + differences.Tables[4].Source.Columns[2].ComputedExpression.Should().BeNull(); + differences.Tables[4].Source.Columns[2].IsComputed.Should().BeFalse(); + differences.Tables[4].Source.Columns[2].Identity.Should().BeNull(); + differences.Tables[4].Source.Columns[2].IsNullable.Should().BeFalse(); + differences.Tables[4].Source.Columns[2].MaxLength.Should().Be(4); + differences.Tables[4].Source.Columns[2].Name.Should().Be("SourceForeignKeyId"); + differences.Tables[4].Source.Columns[2].Position.Should().Be(3); + differences.Tables[4].Source.Columns[2].Precision.Should().Be(10); + differences.Tables[4].Source.Columns[2].Scale.Should().Be(0); + differences.Tables[4].Source.Columns[2].TypeName.Should().Be("int"); + differences.Tables[4].Source.Indexes.Should().HaveCount(2); + differences.Tables[4].Source.Indexes[0].Columns.Should().HaveCount(1); + differences.Tables[4].Source.Indexes[0].Columns[0].Name.Should().Be("SourceName"); + differences.Tables[4].Source.Indexes[0].Columns[0].Position.Should().Be(1); + differences.Tables[4].Source.Indexes[0].Filter.Should().Be("([SourceName]='')"); + differences.Tables[4].Source.Indexes[0].IncludedColumns.Should().HaveCount(1); + differences.Tables[4].Source.Indexes[0].IncludedColumns[0].Name.Should().Be("SourceForeignKeyId"); + differences.Tables[4].Source.Indexes[0].IncludedColumns[0].Position.Should().Be(1); + differences.Tables[4].Source.Indexes[0].IsUnique.Should().BeFalse(); + differences.Tables[4].Source.Indexes[0].Name.Should().Be("IndexSource"); + differences.Tables[4].Source.Indexes[1].Columns.Should().HaveCount(1); + differences.Tables[4].Source.Indexes[1].Columns[0].Name.Should().Be("Id"); + differences.Tables[4].Source.Indexes[1].Columns[0].Position.Should().Be(1); + differences.Tables[4].Source.Indexes[1].Filter.Should().BeNull(); + differences.Tables[4].Source.Indexes[1].IncludedColumns.Should().HaveCount(0); + differences.Tables[4].Source.ForeignKeys.Should().HaveCount(1); + differences.Tables[4].Source.ForeignKeys[0].Columns.Should().HaveCount(1); + differences.Tables[4].Source.ForeignKeys[0].Columns[0].Name.Should().Be("SourceForeignKeyId"); + differences.Tables[4].Source.ForeignKeys[0].Columns[0].Position.Should().Be(1); + differences.Tables[4].Source.ForeignKeys[0].DeleteAction.Should().Be("NO_ACTION"); + differences.Tables[4].Source.ForeignKeys[0].Name.Should().Be("ForeignKeySource"); + differences.Tables[4].Source.ForeignKeys[0].ReferencedTable.Should().Be("ReferencedTable"); + differences.Tables[4].Source.ForeignKeys[0].UpdateAction.Should().Be("NO_ACTION"); + differences.Tables[4].Source.Name.Should().Be("TableSource"); + differences.Tables[4].Source.Schema.Should().Be("dbo"); + differences.Tables[4].Source.PrimaryKey.Name.Should().Be("PrimaryKeySource"); + differences.Tables[4].Source.PrimaryKey.Type.Should().Be("CLUSTERED"); + differences.Tables[4].Source.Triggers.Should().HaveCount(1); + differences.Tables[4].Source.Triggers[0].Name.Should().Be("TriggerSource"); + differences.Tables[4].Source.Triggers[0].Code.Should().Be("CREATE TRIGGER [TriggerSource]\r\n\tON [dbo].[TableSource]\r\n\tFOR DELETE, INSERT, UPDATE\r\n\tAS\r\n\tBEGIN\r\n\t\tSET NOCOUNT ON\r\n\tEND"); + differences.Tables[4].Source.Triggers[0].IsInsteadOfTrigger.Should().BeFalse(); + differences.Tables[4].Source.UniqueConstraints.Should().HaveCount(1); + differences.Tables[4].Source.UniqueConstraints[0].Columns.Should().HaveCount(1); + differences.Tables[4].Source.UniqueConstraints[0].Columns[0].Name.Should().Be("Id"); + differences.Tables[4].Source.UniqueConstraints[0].Columns[0].Position.Should().Be(1); + differences.Tables[4].Source.UniqueConstraints[0].Name.Should().Be("UniqueConstraintSource"); + differences.Tables[4].Source.UniqueConstraints[0].Type.Should().Be("NONCLUSTERED"); + differences.Tables[4].Target.Should().BeNull(); + differences.Tables[4].Triggers.Should().BeEmpty(); + differences.Tables[4].Type.Should().Be(SqlObjectDifferenceType.MissingInTarget); // UserTypes differences.UserTypes.Should().HaveCount(3);