Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dotnet EF Core Failed when add a second migration with Data #21576

Closed
leandrofagundes opened this issue Jul 10, 2020 · 3 comments
Closed

Dotnet EF Core Failed when add a second migration with Data #21576

leandrofagundes opened this issue Jul 10, 2020 · 3 comments

Comments

@leandrofagundes
Copy link

I have one migration with the default data seed on a few tables.
Now, everytime I have a change to my schema, I have to drop, delete the migrations and recreate everything because if I tried to
add migrations, it gives me the error:

Build started...
Build succeeded.
info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
Entity Framework Core 3.0.1 initialized 'SqlServerDbContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None
System.InvalidOperationException: Failed to compare two elements in the array.
---> System.ArgumentException: At least one object must implement IComparable.
at System.Collections.Comparer.Compare(Object a, Object b)
at System.Collections.Generic.ObjectComparer1.Compare(T x, T y) at Microsoft.EntityFrameworkCore.Update.Internal.ModificationCommandComparer.Compare(ModificationCommand x, ModificationCommand y) at System.Collections.Generic.ArraySortHelper1.InsertionSort(T[] keys, Int32 lo, Int32 hi, Comparison1 comparer) at System.Collections.Generic.ArraySortHelper1.IntroSort(T[] keys, Int32 lo, Int32 hi, Int32 depthLimit, Comparison1 comparer) at System.Collections.Generic.ArraySortHelper1.IntrospectiveSort(T[] keys, Int32 left, Int32 length, Comparison1 comparer) at System.Collections.Generic.ArraySortHelper1.Sort(T[] keys, Int32 index, Int32 length, IComparer1 comparer) --- End of inner exception stack trace --- at System.Collections.Generic.ArraySortHelper1.Sort(T[] keys, Int32 index, Int32 length, IComparer1 comparer) at System.Array.Sort[T](T[] array, Int32 index, Int32 length, IComparer1 comparer)
at System.Collections.Generic.List1.Sort(Int32 index, Int32 count, IComparer1 comparer)
at Microsoft.EntityFrameworkCore.Update.Internal.CommandBatchPreparer.BatchCommands(IList1 entries, IUpdateAdapter updateAdapter)+MoveNext() at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.GetDataOperations(DiffContext diffContext)+MoveNext() at System.Linq.Enumerable.ConcatIterator1.MoveNext()
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.Sort(IEnumerable1 operations, DiffContext diffContext) at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.GetDifferences(IModel source, IModel target) at Microsoft.EntityFrameworkCore.Migrations.Design.MigrationsScaffolder.ScaffoldMigration(String migrationName, String rootNamespace, String subNamespace, String language) at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_0.<.ctor>b__0() at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_01.b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
Failed to compare two elements in the array.

Steps to reproduce

  1. Create a few domain objects
  2. Create the configurations using the configuration builder and insert default data with builder.HasData.
  3. Create a migration.
  4. Create more domains.
  5. Try to create migrations again.

Example:

internal sealed class ClaimConfiguration : IEntityTypeConfiguration<Claim>
    {
        public void Configure(EntityTypeBuilder<Claim> builder)
        {
            builder.ToTable("Claim");

            BuildIndexes(builder);

            BuildProperties(builder);

            TableSeed(builder);
        }

        private void BuildIndexes(EntityTypeBuilder<Claim> builder)
        {
            builder.HasKey(m => m.Id);
            builder.HasIndex(m => m.Name).IsUnique();
        }

        private void BuildProperties(EntityTypeBuilder<Claim> builder)
        {
            builder.Property(m => m.Id)
                .HasConversion(p => p.ToGuid(), p => new ClaimId(p))
                .IsRequired();

            builder.Property(p => p.Name)
                .HasConversion(p => p.ToString(), p => new ClaimName(p))
                .HasMaxLength(60);
        }

        private void TableSeed(EntityTypeBuilder<Claim> builder)
        {
            builder.HasData(
                new Claim(ClaimIdConstants.ClaimsView, ClaimNameConstants.ClaimsView),
                new Claim(ClaimIdConstants.RolesView, ClaimNameConstants.RolesView),
                new Claim(ClaimIdConstants.UsersManage, ClaimNameConstants.UsersManage),
                new Claim(ClaimIdConstants.UsersClaimsManage, ClaimNameConstants.UsersClaimsManage),
                new Claim(ClaimIdConstants.UsersRolesManage, ClaimNameConstants.UsersRolesManage),
                new Claim(ClaimIdConstants.EstablishmentsManage, ClaimNameConstants.EstablishmentsManage),
                new Claim(ClaimIdConstants.EstablishmentsClaimsManage, ClaimNameConstants.EstablishmentsClaimsManage),
                new Claim(ClaimIdConstants.OffersManage, ClaimNameConstants.OffersManage));
        }
    }

For dotnet ef and PMC, share the --verbose output

System.ArgumentException: At least one object must implement IComparable.
at System.Collections.Comparer.Compare(Object a, Object b)
at System.Collections.Generic.ObjectComparer1.Compare(T x, T y) at Microsoft.EntityFrameworkCore.Update.Internal.ModificationCommandComparer.Compare(ModificationCommand x, ModificationCommand y) at System.Collections.Generic.ArraySortHelper1.InsertionSort(T[] keys, Int32 lo, Int32 hi, Comparison1 comparer) at System.Collections.Generic.ArraySortHelper1.IntroSort(T[] keys, Int32 lo, Int32 hi, Int32 depthLimit, Comparison1 comparer) at System.Collections.Generic.ArraySortHelper1.IntrospectiveSort(T[] keys, Int32 left, Int32 length, Comparison1 comparer) at System.Collections.Generic.ArraySortHelper1.Sort(T[] keys, Int32 index, Int32 length, IComparer1 comparer) --- End of inner exception stack trace --- at System.Collections.Generic.ArraySortHelper1.Sort(T[] keys, Int32 index, Int32 length, IComparer1 comparer) at System.Array.Sort[T](T[] array, Int32 index, Int32 length, IComparer1 comparer)
at System.Collections.Generic.List1.Sort(Int32 index, Int32 count, IComparer1 comparer)
at Microsoft.EntityFrameworkCore.Update.Internal.CommandBatchPreparer.BatchCommands(IList1 entries, IUpdateAdapter updateAdapter)+MoveNext() at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.GetDataOperations(DiffContext diffContext)+MoveNext() at System.Linq.Enumerable.ConcatIterator1.MoveNext()
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.Sort(IEnumerable1 operations, DiffContext diffContext) at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.GetDifferences(IModel source, IModel target) at Microsoft.EntityFrameworkCore.Migrations.Design.MigrationsScaffolder.ScaffoldMigration(String migrationName, String rootNamespace, String subNamespace, String language) at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_0.<.ctor>b__0() at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_01.b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
Failed to compare two elements in the array.

Further technical details

EF Core version: 3.1.5
Database provider: Sql Server
Target framework: ASP.NET Core 3.1
Operating system: Windows 10
IDE: Visual Studio 2019 16.3

@ajcvickers
Copy link
Member

Please attach a small, runnable project or post a small, runnable code listing that reproduces what you are seeing so that we can investigate.

@leandrofagundes
Copy link
Author

EFCoreDataMigrationSample.zip

You need a SQL SERVER database Named EFCoreSample (empty).

  1. Download the attachment and extract to any folder.
  2. Open the solution file: \EFCoreDataMigrationSample\EFCoreDataMigrationSample.sln using a VS2019.
  3. Build the solution (Ctrl+Shift+B).
  4. Type dotnet-ef migrations add dev001 --project .\SQLDataBase\SQLDataBase.csproj --startup-project .\API\API.csproj in your Package Manager Console
  5. Type dotnet-ef database update --project .\SQLDataBase\SQLDataBase.csproj --startup-project .\API\API.csproj in your Package Manager console.

Now you can see on your EFCoreSample database created and seed on your sql server.

  1. On file IRole of Domains project, uncomment line 10.
  2. On file Role of Domains project, uncomment lines 12 and 18.
  3. On file RoleConfiguration on SQLDatabase project, folder DatabaseConfigs, uncomment line 38.
  4. Type dotnet-ef migrations add dev002 --project .\SQLDataBase\SQLDataBase.csproj --startup-project .\API\API.csproj on your package manager console.
    The migration will fail.

If you clean everything (database and migrations) it will work.

  1. Type dotnet-ef database update 0 --project .\SQLDataBase\SQLDataBase.csproj --startup-project .\API\API.csproj on your Package Manager Console.
  2. Type dotnet-ef migrations remove --project .\SQLDataBase\SQLDataBase.csproj --startup-project .\API\API.csproj on your package manager console.
  3. Check your database, the Role table is gone.
  4. Type dotnet-ef migrations add dev003 --project .\SQLDataBase\SQLDataBase.csproj --startup-project .\API\API.csproj on your package manager console.
  5. Type dotnet-ef database update --project .\SQLDataBase\SQLDataBase.csproj --startup-project .\API\API.csproj on your package manager console.

The table Role is there with the new columns (CreatedOn) and no errors. If you change anything and try to do a new migration after this one, the errors popup again.

@ajcvickers
Copy link
Member

@leandrofagundes Thanks. I was able to reproduce this on 3.1.5, but the issue is fixed in the latest 5.0 preview. I believe it has the same root cause as #13507.

@ajcvickers ajcvickers reopened this Oct 16, 2022
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants