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

Scaffolding fails: "The annotation 'MySql:IndexPrefixLength' cannot be added because an annotation with the same name already exists." #1189

Closed
engstrand opened this issue Oct 12, 2020 · 7 comments · Fixed by #1190
Assignees
Labels
Milestone

Comments

@engstrand
Copy link

engstrand commented Oct 12, 2020

Scaffolding existing DB that was successfully scaffolded using MS package in same project:

Scaffold-DbContext "server=localhost;user=user;password=password;database=mysql_db" "Pomelo.EntityFrameworkCore.MySql" -OutputDir EF

The process ends pretty much immiediately with exception and stacktrace below.

Exception message
System.InvalidOperationException: The annotation 'MySql:IndexPrefixLength' cannot be added because an annotation with the same name already exists.

Stack trace

 at Microsoft.EntityFrameworkCore.Infrastructure.Annotatable.AddAnnotation(String name, Annotation annotation)
   at Microsoft.EntityFrameworkCore.Infrastructure.Annotatable.AddAnnotation(String name, Object value)
   at Microsoft.EntityFrameworkCore.Infrastructure.Annotatable.Microsoft.EntityFrameworkCore.Metadata.IMutableAnnotatable.AddAnnotation(String name, Object value)
   at Microsoft.EntityFrameworkCore.MutableAnnotatableExtensions.AddAnnotations(IMutableAnnotatable annotatable, IEnumerable`1 annotations)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.RelationalScaffoldingModelFactory.VisitIndex(EntityTypeBuilder builder, DatabaseIndex index)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.RelationalScaffoldingModelFactory.VisitIndexes(EntityTypeBuilder builder, ICollection`1 indexes)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.RelationalScaffoldingModelFactory.VisitTable(ModelBuilder modelBuilder, DatabaseTable table)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.RelationalScaffoldingModelFactory.VisitTables(ModelBuilder modelBuilder, ICollection`1 tables)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.RelationalScaffoldingModelFactory.VisitDatabaseModel(ModelBuilder modelBuilder, DatabaseModel databaseModel)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.RelationalScaffoldingModelFactory.Create(DatabaseModel databaseModel, Boolean useDatabaseNames)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.ReverseEngineerScaffolder.ScaffoldModel(String connectionString, DatabaseModelFactoryOptions databaseOptions, ModelReverseEngineerOptions modelOptions, ModelCodeGenerationOptions codeOptions)
   at Microsoft.EntityFrameworkCore.Design.Internal.DatabaseOperations.ScaffoldContext(String provider, String connectionString, String outputDir, String outputContextDir, String dbContextClassName, IEnumerable`1 schemas, IEnumerable`1 tables, Boolean useDataAnnotations, Boolean overwriteFiles, Boolean useDatabaseNames)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.ScaffoldContextImpl(String provider, String connectionString, String outputDir, String outputDbContextDir, String dbContextClassName, IEnumerable`1 schemaFilters, IEnumerable`1 tableFilters, Boolean useDataAnnotations, Boolean overwriteFiles, Boolean useDatabaseNames)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.ScaffoldContext.<>c__DisplayClass0_0.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)

Further technical details

MySQL version: 5.7.18
Operating system: Windows 10
Pomelo.EntityFrameworkCore.MySql version: 3.2.2
Microsoft.AspNetCore.App version: 3.1

@mguinness
Copy link
Collaborator

The interesting thing is that Pomelo.EntityFrameworkCore.MySql isn't even shown in stack trace, What happens if you create a new project and try to scaffold the db?

@engstrand
Copy link
Author

I have created a new project but the result was the same.

@engstrand
Copy link
Author

engstrand commented Oct 12, 2020

Could it be related to this: dotnet/efcore#11846 ?

@mguinness
Copy link
Collaborator

Can you isolate it to a certain table w/ the Tables option? If so, please share the schema of the table.

@lauxjpn
Copy link
Collaborator

lauxjpn commented Oct 12, 2020

Could it be related to this: dotnet/efcore#11846 ?

I can confirm, that the moment two indices are used for the same column, and both are using a prefix length, I can reproduce the exception:

CREATE TABLE `Test` (
  `TestId` int NOT NULL AUTO_INCREMENT,
  `LongString` varchar(12000) DEFAULT NULL,
  PRIMARY KEY (`TestId`),
  KEY `IX_LongString` (`LongString`(120)),
  KEY `IX_LongString2` (`LongString`(100))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

Scaffold command:

dotnet ef dbcontext scaffold "server=127.0.0.1;uid=root;pwd=;port=3308;database=Issue1189" Pomelo.EntityFrameworkCore.MySql -c Context -o Models --verbose --force

Output:

Using assembly 'IssueConsoleTemplate'.
Using startup assembly 'IssueConsoleTemplate'.
Using application base 'E:\Sources\PomeloIssues\Issue1189\IssueConsoleTemplate\bin\Debug\netcoreapp3.1'.
Using working directory 'E:\Sources\PomeloIssues\Issue1189\IssueConsoleTemplate'.
Using root namespace 'IssueConsoleTemplate'.
Using project directory 'E:\Sources\PomeloIssues\Issue1189\IssueConsoleTemplate\'.
Remaining arguments: .
Finding design-time services for provider 'Pomelo.EntityFrameworkCore.MySql'...
Using design-time services from provider 'Pomelo.EntityFrameworkCore.MySql'.
Finding design-time services referenced by assembly 'IssueConsoleTemplate'.
No referenced design-time services were found.
Finding IDesignTimeServices implementations in assembly 'IssueConsoleTemplate'...
No design-time services were found.
System.InvalidOperationException: The annotation 'MySql:IndexPrefixLength' cannot be added because an annotation with the same name already exists.
   at Microsoft.EntityFrameworkCore.Infrastructure.Annotatable.AddAnnotation(String name, Annotation annotation) in E:\Sources\EntityFrameworkCore-3.1\src\EFCore\Infrastructure\Annotatable.cs:line 61
   at Microsoft.EntityFrameworkCore.Infrastructure.Annotatable.AddAnnotation(String name, Object value) in E:\Sources\EntityFrameworkCore-3.1\src\EFCore\Infrastructure\Annotatable.cs:line 45
   at Microsoft.EntityFrameworkCore.Infrastructure.Annotatable.Microsoft.EntityFrameworkCore.Metadata.IMutableAnnotatable.AddAnnotation(String name, Object value) in E:\Sources\EntityFrameworkCore-3.1\src\EFCore\Infrastructure\Annotatable.cs:line 209
   at Microsoft.EntityFrameworkCore.MutableAnnotatableExtensions.AddAnnotations(IMutableAnnotatable annotatable, IEnumerable`1 annotations) in E:\Sources\EntityFrameworkCore-3.1\src\EFCore\Extensions\MutableAnnotatableExtensions.cs:line 38
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.RelationalScaffoldingModelFactory.VisitIndex(EntityTypeBuilder builder, DatabaseIndex index) in E:\Sources\EntityFrameworkCore-3.1\src\EFCore.Design\Scaffolding\Internal\RelationalScaffoldingModelFactory.cs:line 668
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.RelationalScaffoldingModelFactory.VisitIndexes(EntityTypeBuilder builder, ICollection`1 indexes) in E:\Sources\EntityFrameworkCore-3.1\src\EFCore.Design\Scaffolding\Internal\RelationalScaffoldingModelFactory.cs:line 623
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.RelationalScaffoldingModelFactory.VisitTable(ModelBuilder modelBuilder, DatabaseTable table) in E:\Sources\EntityFrameworkCore-3.1\src\EFCore.Design\Scaffolding\Internal\RelationalScaffoldingModelFactory.cs:line 361
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.RelationalScaffoldingModelFactory.VisitTables(ModelBuilder modelBuilder, ICollection`1 tables) in E:\Sources\EntityFrameworkCore-3.1\src\EFCore.Design\Scaffolding\Internal\RelationalScaffoldingModelFactory.cs:line 304
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.RelationalScaffoldingModelFactory.VisitDatabaseModel(ModelBuilder modelBuilder, DatabaseModel databaseModel) in E:\Sources\EntityFrameworkCore-3.1\src\EFCore.Design\Scaffolding\Internal\RelationalScaffoldingModelFactory.cs:line 197
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.RelationalScaffoldingModelFactory.Create(DatabaseModel databaseModel, Boolean useDatabaseNames) in E:\Sources\EntityFrameworkCore-3.1\src\EFCore.Design\Scaffolding\Internal\RelationalScaffoldingModelFactory.cs:line 108
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.ReverseEngineerScaffolder.ScaffoldModel(String connectionString, DatabaseModelFactoryOptions databaseOptions, ModelReverseEngineerOptions modelOptions, ModelCodeGenerationOptions codeOptions) in E:\Sources\EntityFrameworkCore-3.1\src\EFCore.Design\Scaffolding\Internal\ReverseEngineerScaffolder.cs:line 108
   at Microsoft.EntityFrameworkCore.Design.Internal.DatabaseOperations.ScaffoldContext(String provider, String connectionString, String outputDir, String outputContextDir, String dbContextClassName, IEnumerable`1 schemas, IEnumerable`1 tables, Boolean useDataAnnotations, Boolean overwriteFiles, Boolean useDatabaseNames) in E:\Sources\EntityFrameworkCore-3.1\src\EFCore.Design\Design\Internal\DatabaseOperations.cs:line 96
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.ScaffoldContextImpl(String provider, String connectionString, String outputDir, String outputDbContextDir, String dbContextClassName, IEnumerable`1 schemaFilters, IEnumerable`1 tableFilters, Boolean useDataAnnotations, Boolean overwriteFiles, Boolean useDatabaseNames) in E:\Sources\EntityFrameworkCore-3.1\src\EFCore.Design\Design\OperationExecutor.cs:line 491
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.ScaffoldContext.<>c__DisplayClass0_1.<.ctor>b__0() in E:\Sources\EntityFrameworkCore-3.1\src\EFCore.Design\Design\OperationExecutor.cs:line 468
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0() in E:\Sources\EntityFrameworkCore-3.1\src\EFCore.Design\Design\OperationExecutor.cs:line 605
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action) in E:\Sources\EntityFrameworkCore-3.1\src\EFCore.Design\Design\OperationExecutor.cs:line 588
The annotation 'MySql:IndexPrefixLength' cannot be added because an annotation with the same name already exists.

@engstrand
Copy link
Author

Great, that is useful information!
I could check my tables and maybe modify/remove some index to get around this.
But how come this went well using MS packages?

@lauxjpn
Copy link
Collaborator

lauxjpn commented Oct 13, 2020

But how come this went well using MS packages?

I don't think SQL Server uses index prefixes at all. I guess you must have converted the MSSQL database somehow to MySQL. In the conversion process, the index prefixes must have been added (which should be correct).

The issue are not the index prefixes themselves, but annotations that are being set for those prefixes by us for the index. Because of dotnet/efcore#11846 you referenced above (an EF Core bug), indices with the same set of columns are being merged by EF Core into one index. But then, setting the same annotation again, from the second database index to the merged EF Core index, throws an exception.


We implemented a workaround for this with #1190.
The fix will make it into the 3.2.3 version which will be released tomorrow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants