question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Do not map annotation to database during migrations

See original GitHub issue

Ask a question

I’ve read the docs, searched StackOverflow and tried my best to dig into past issues. The best I could find was this but the method signatures seem to have changed since then.

I am trying to understand the “annotations” feature but it is undocumented.

When building a model I use this:

MyAnnotation value = GetSomeComplexObjectToUseAsAnnotation();
entityTypeBuilder
  .Property(x => x.Name)
  .HasAnnotation("SomeKey", value);

And later I can retrieve it using something like this:

context
  .Model
  .GetEntityTypes()
  .SelectMany(x => x.GetProperties())
  .Select(x => x.FindAnnotation("SomeKey")?.Value)
  .Where(x => x is MyAnnotation);

I use it as a way to pass around info concerning the model, which I can use for various purposes. That works!

But dotnet ef migrations add throws:

System.InvalidOperationException: Cannot scaffold C# literals of type ‘MyAnnotation’. The provider should implement CoreTypeMapping.GenerateCodeLiteral to support using it at design time. at Microsoft.EntityFrameworkCore.Design.Internal.CSharpHelper.UnknownLiteral(Object value) at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpSnapshotGenerator.GenerateAnnotation(IAnnotation annotation, IndentedStringBuilder stringBuilder) at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpSnapshotGenerator.GenerateAnnotations(IEnumerable1 annotations, IndentedStringBuilder stringBuilder) at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpSnapshotGenerator.GeneratePropertyAnnotations(IProperty property, IndentedStringBuilder stringBuilder) at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpSnapshotGenerator.GenerateProperty(String builderName, IProperty property, IndentedStringBuilder stringBuilder) at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpSnapshotGenerator.GenerateProperties(String builderName, IEnumerable1 properties, IndentedStringBuilder stringBuilder) at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpSnapshotGenerator.GenerateEntityType(String builderName, IEntityType entityType, IndentedStringBuilder stringBuilder) at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpSnapshotGenerator.GenerateEntityTypes(String builderName, IReadOnlyList1 entityTypes, IndentedStringBuilder stringBuilder) at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpSnapshotGenerator.Generate(String builderName, IModel model, IndentedStringBuilder stringBuilder) at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGenerator.GenerateMetadata(String migrationNamespace, Type contextType, String migrationName, String migrationId, IModel targetModel) 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, String namespace) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType, String namespace) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_0.<.ctor>b__0() at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_01.<Execute>b__0() at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)

I assume the problem is the migration system is expecting a primitive type, but it gets an instance of MyAnnotation and doesn’t know how to map that to the database - but I don’t want it in the database.

In the post I linked above ajcvickers said:

since many annotations only affect runtime behavior, not the database schema.

So I assume (?) I can use the annotation system this way. How do I tell migrations to not map that annotation?

Include provider and version information

EF Core version: 5.0.11 Database provider: sqlite, postgres Target framework: dotnet5 Operating system: linux IDE: vscode 1.63.0

Thank you!

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:9 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
bricelamcommented, Jan 4, 2022

Looks like you should be able to replace the IAnnotationCodeGenerator service and override AnnotationCodeGenerator.FilterIgnoredAnnotations to add exclusions.

1reaction
lonix1commented, Jan 7, 2022

LOL you schooled me!

The docs say

This implementation returns false for all ‘IsHandledByConvention’ methods and null for all ‘GenerateFluentApi’ methods. Providers should override for the annotations that they understand.

So I fiddled with those and presumably that was the problem. I’ve since learned I don’t need to change anything other than the filter method, as you explained.

This very simple code works, for anyone who needs it:

public class MyDesignTimeServices : IDesignTimeServices
{
  public void ConfigureDesignTimeServices(IServiceCollection services)
    => services.AddSingleton<IAnnotationCodeGenerator, MyAnnotationCodeGenerator>();
}

public class MyAnnotationCodeGenerator : AnnotationCodeGenerator
{
  public MyAnnotationCodeGenerator(AnnotationCodeGeneratorDependencies dependencies) : base(dependencies) { }
  public override IEnumerable<IAnnotation> FilterIgnoredAnnotations(IEnumerable<IAnnotation> annotations) => 
    base.FilterIgnoredAnnotations(annotations).Where(a => a.Name != "SomeKey");
}

Thanks guys!

Read more comments on GitHub >

github_iconTop Results From Across the Web

The NotMapped Attribute
The NotMapped attribute is used to specify that an entity or property is not to be mapped to a table or column in...
Read more >
DataAnnotations - NotMapped Attribute in EF 6 & EF Core
The NotMapped attribute can be applied to properties of an entity class for which we do not want to create corresponding columns in...
Read more >
How to exclude one table from automatic code first ...
I'm using the Entity Framework in the Code First mode with automatic migrations enabled. Now, I have one entity whose table should not...
Read more >
Code First Data Annotations - EF6
With DataAnnotations you can not only drive database schema generation, but you can also map your code first classes to a pre-existing database....
Read more >
Data Annotations and Code First Migration in Entity ...
Data Annotations are useful in the Entity Framework that we can apply to our model class and can enforce the validations further.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found