Migrating Microsoft.EntityFrameworkCore.SqlServer.Migrations.Internal override to .net 5

Bart K 1 Reputation point
2020-12-11T11:51:55.837+00:00

Hello,
I'm migrating my code from .net core 3.1 to .net 5.0
All works well except for one thing.
On my columns in my Entities I have created a custom Annotation
like this

[CustomAnnotiation("Some key", "Interval in ms")]
        public int Interval { get; set; }

when using add-migation,
this annotation was added to the dbcontext and also migration script like this

migrationBuilder.AlterColumn<int>(
                name: "Interval",
                table: "Tables",
                nullable: false,
                oldClrType: typeof(int),
                oldType: "int")
                .Annotation("CustomAnnotiation:Some key", "Interval in ms");

and when using update-database some custom sql was used.
when updating to .net 5 the annotion to the migration script fails And I can't pinpoint how to fix this.

previously I had an override on
Microsoft.EntityFrameworkCore.SqlServer.Migrations.Internal.SqlServerMigrationsAnnotationProvider.For(IProperty property)
but this method is gone in .net 5.
my override was like this

 public override IEnumerable<IAnnotation> For(IProperty property)
            {
                var result = base.For(property);
                foreach(var annotation in result)
                {
                    yield return annotation;
                }

                var annotations = property.GetAnnotations();
                foreach(var annotation in annotations.Where(a => a.Name.StartsWith("CustomAnnotiation"))
                {
                    yield return new Annotation(
                        annotation.Name,
                        annotation.Value);
                }            
            }

but checking the new EF code I saw IColumn makes his introcuduction,
and seems to be used for generating the Annotations.

Still is seems to be that the annotations are added to the IProperty part, but read from IColumn
where setting _annotiation always is empty.
and I'm missing where to fix this.
can someone help me to point in the correct direction?

.NET Runtime
.NET Runtime
.NET: Microsoft Technologies based on the .NET software framework.Runtime: An environment required to run apps that aren't compiled to machine language.
1,132 questions
{count} votes

3 answers

Sort by: Most helpful
  1. Bart K 1 Reputation point
    2020-12-15T15:45:19.57+00:00

    I found something but I'm not there yet.
    annotions in .net 5 are handled totally different.
    the read part makes is easier, but somehow I need to set them.
    for this I think I need to override method "ProcessPropertyAnnotationChanged" in
    https://github.com/dotnet/efcore/blob/release/5.0/src/EFCore.SqlServer/Metadata/Conventions/SqlServerValueGenerationConvention.cs
    before I used ReplaceService to do that,
    but I cannot do that here, since there is a hard call for the specified class here
    https://github.com/dotnet/efcore/blob/release/5.0/src/EFCore.SqlServer/Metadata/Conventions/SqlServerConventionSetBuilder.cs
    on line 58.
    so my question now is,
    how can I override the SqlServerValueGenerationConvention class, to always use mine which inherits the former class?

     public class MyClassSqlServerValueGenerationConvention :SqlServerValueGenerationConvention
        {
    
    0 comments No comments

  2. Jerry Cai-MSFT 986 Reputation points
    2020-12-16T09:08:03.117+00:00

    Hi,BartK-2269

    To override the method "ProcessPropertyAnnotationChanged", you can do like this way:

    public class MyClassSqlServerValueGenerationConvention :SqlServerValueGenerationConvention
    {
    ....//other codes
    //override the method in SqlServerValueGenerationConvention
    public override void ProcessPropertyAnnotationChanged(
               ......
     )
            {
                .....
                base.ProcessPropertyAnnotationChanged(....);
            }
    
    ....//other codes
    }
    

    Best Regards,
    Jerry Cai


    If the answer is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

  3. Bart K 1 Reputation point
    2020-12-16T11:29:30.71+00:00

    I know that part,
    But I cannot use

    options.ReplaceService<Microsoft.EntityFrameworkCore.Metadata.Conventions.IPropertyAnnotationChangedConvention, DataSyncSqlServerValueGenerationConvention>();
    

    because it won't replace the service.

    I think for that part I need to override
    CreateConventionSet
    as well.
    which means a lot of code copy,
    I hope there is a better way where I don't have to do just that.