Efcore: Error while diffing spatial seed data

Created on 2 Nov 2019  路  13Comments  路  Source: dotnet/efcore

Diffing the model snapshot against the original model in ModelSnapshotSqlServerTest.SeedData_annotations_are_stored_in_snapshot() results in the following exception.

System.ArgumentException: Operation does not support GeometryCollection arguments
   at NetTopologySuite.Geometries.Geometry.CheckNotGeometryCollection(Geometry g)
   at NetTopologySuite.Geometries.Geometry.Relate(Geometry g)
   at NetTopologySuite.Geometries.Geometry.EqualsTopologically(Geometry g)
   at Microsoft.EntityFrameworkCore.ChangeTracking.ValueComparer`1.Equals(T left, T right) in src\EFCore\ChangeTracking\ValueComparer`.cs:line 230
   at Microsoft.EntityFrameworkCore.ChangeTracking.ValueComparer`1.Equals(Object left, Object right) in src\EFCore\ChangeTracking\ValueComparer`.cs:line 212
   at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.DiffData(TableMapping source, TableMapping target, DiffContext diffContext) in src\EFCore.Relational\Migrations\Internal\MigrationsModelDiffer.cs:line 1811
   at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.Diff(TableMapping source, TableMapping target, DiffContext diffContext)+MoveNext() in src\EFCore.Relational\Migrations\Internal\MigrationsModelDiffer.cs:line 605
   at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.DiffCollection[T](IEnumerable`1 sources, IEnumerable`1 targets, DiffContext diffContext, Func`4 diff, Func`3 add, Func`3 remove, Func`4[] predicates)+MoveNext() in src\EFCore.Relational\Migrations\Internal\MigrationsModelDiffer.cs:line 2097
   at System.Linq.Enumerable.ConcatIterator`1.MoveNext()
   at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.Sort(IEnumerable`1 operations, DiffContext diffContext) in src\EFCore.Relational\Migrations\Internal\MigrationsModelDiffer.cs:line 189
   at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.GetDifferences(IModel source, IModel target) in src\EFCore.Relational\Migrations\Internal\MigrationsModelDiffer.cs:line 153
   at Microsoft.EntityFrameworkCore.Migrations.ModelSnapshotSqlServerTest.Test(IModel model, String expectedCode, Action`2 assert) in test\EFCore.Design.Tests\Migrations\ModelSnapshotSqlServerTest.cs:line 3749
   at Microsoft.EntityFrameworkCore.Migrations.ModelSnapshotSqlServerTest.Test(Action`1 buildModel, String expectedCode, Action`2 assert) in test\EFCore.Design.Tests\Migrations\ModelSnapshotSqlServerTest.cs:line 3673
   at Microsoft.EntityFrameworkCore.Migrations.ModelSnapshotSqlServerTest.SeedData_annotations_are_stored_in_snapshot() in test\EFCore.Design.Tests\Migrations\ModelSnapshotSqlServerTest.cs:line 3174
closed-duplicate

Most helpful comment

@roji Looks like it's working now! It didn't work for the InMemory-db though ("fixed" it with Database.IsSqlServer()). I keep forgetting how modular and customizable EF Core actually is!

All 13 comments

Possibly external (https://github.com/NetTopologySuite/NetTopologySuite/issues/213)

Didn't we switch to EqualsExact for query translation? We may want to do the same for the value comparer...

This may have been fixed by that change. I didn鈥檛 try reproing again

Sorry, I wrote some nonsense - #18946 did change GeometryValueComparer to use EqualsExact instead of EqualsTopologically; this is in 5.0.0-preview1. So there's a very good chance this is just a dup of #18921.

I seem to get this on SaveChanges as well:

System.ArgumentException:
   at NetTopologySuite.Geometries.Geometry.CheckNotGeometryCollection (NetTopologySuite, Version=2.0.0.0, Culture=neutral, PublicKeyToken=f580a05016ebada1)
   at NetTopologySuite.Geometries.Geometry.Relate (NetTopologySuite, Version=2.0.0.0, Culture=neutral, PublicKeyToken=f580a05016ebada1)
   at NetTopologySuite.Geometries.Geometry.EqualsTopologically (NetTopologySuite, Version=2.0.0.0, Culture=neutral, PublicKeyToken=f580a05016ebada1)
   at lambda_method (Anonymously Hosted DynamicMethods Assembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)
   at Microsoft.EntityFrameworkCore.ChangeTracking.ValueComparer`1.Equals (Microsoft.EntityFrameworkCore, Version=3.1.4.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
   at Microsoft.EntityFrameworkCore.ChangeTracking.ValueComparer`1.Equals (Microsoft.EntityFrameworkCore, Version=3.1.4.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.ChangeDetector.LocalDetectChanges (Microsoft.EntityFrameworkCore, Version=3.1.4.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.ChangeDetector.DetectChanges (Microsoft.EntityFrameworkCore, Version=3.1.4.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
   at Microsoft.EntityFrameworkCore.ChangeTracking.ChangeTracker.DetectChanges (Microsoft.EntityFrameworkCore, Version=3.1.4.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
   at Microsoft.EntityFrameworkCore.DbContext.TryDetectChanges (Microsoft.EntityFrameworkCore, Version=3.1.4.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
   at Microsoft.EntityFrameworkCore.DbContext+<SaveChangesAsync>d__54.MoveNext (Microsoft.EntityFrameworkCore, Version=3.1.4.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)

I tried to upgrade to 5-preview4 and the issue seems to be resolved there. Is there any workaround for EF Core 3? Not sure I want to use a preview version in production...

@OskarKlintrot you can copy GeometryValueComparer.cs and make the switch to EqualsExact just like #18946 did. See these docs about value comparers.

@roji Thanks, that shouldn't be any problem! I where just looking through the source code instead of the docs to see how to get it working, I followed the new GeometryValueComparer() up to SqlServerNetTopologySuiteTypeMappingSourcePlugin but that seemed a bit overkill to replace :)

@OskarKlintrot yep, you shouldn't need to do anything with the plugin - just configure the modified value comparer on the spatial properties where this is a problem.

@roji Looks like it's working now! It didn't work for the InMemory-db though ("fixed" it with Database.IsSqlServer()). I keep forgetting how modular and customizable EF Core actually is!

Given this discussion it seems this could be a duplicate of #18921 ans is therefore likely fixed.

Confirmed, repro'd the bug on 3.1.4, and it's gone in 5.0.0-preview4.


Repro

```c#
class Program
{
static async Task Main(string[] args)
{
await using var ctx = new BlogContext();
await ctx.Database.EnsureDeletedAsync();
await ctx.Database.EnsureCreatedAsync();
}
}

public class BlogContext : DbContext
{
public DbSet Blogs { get; set; }

static ILoggerFactory ContextLoggerFactory
    => LoggerFactory.Create(b => b.AddConsole().AddFilter("", LogLevel.Information));

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .UseNpgsql(@"Host=localhost;Username=test;Password=test", o => o.UseNetTopologySuite())
        .EnableSensitiveDataLogging()
        .UseLoggerFactory(ContextLoggerFactory);

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.HasPostgresExtension("postgis");

    modelBuilder.Entity<Blog>().HasData(new Blog
    {
        Id = 1,
        SomeGeometry = new GeometryCollection(new[] { new Point(1, 1) })
    });
}

}

public class Blog
{
public int Id { get; set; }
public Geometry SomeGeometry { get; set; }
}
```

Duplicate of #18921

Was this page helpful?
0 / 5 - 0 ratings