如何向 EF Core SqlServer 目标构建器添加对结构化注释的支持?

How to add the support for structured annotations to the EF Core SqlServer target builder?

使用接受 object 类型参数的 HasAnnotation 方法很容易将纯字符串注释添加到 EF 模型,但尝试添加结构化注释时,您将在构建迁移时出错:

        modelBuilder.Entity<Group>().HasAnnotation($"{GetType().FullName}.Constraint3", new ValueTuple<string,string>( "aaa", "bbb" ));

The current CSharpHelper cannot scaffold literals of type 'System.ValueTuple`2[System.String,System.String]'. Configure your services to use one that can.

        modelBuilder.Entity<Group>().HasAnnotation($"{GetType().FullName}.Constraint2", new[] { "aaa", "bbb" });

The current CSharpHelper cannot scaffold literals of type 'System.String[]'. Configure your services to use one that can.

我们是否有办法向 target builder 注入有助于序列化结构化注释的方法?

为什么我需要它?只是试图在一个地方收集所有数据库元数据。元通常是结构化信息。

据我了解(没有太多相关信息),想法是使用简单的名称/值对,其中值是原始类型(stringint, decimal, DateTime 等加上 enums) 和名称构成结构。所有 EF Core 注释都遵循该原则。例如,名称:"SqlServer:ValueGenerationStrategy" 类型:SqlServerValueGenerationStrategy

可能最简单的方法就是简单地遵循该约定。不过不管怎么说,负责的服务是ICSharpHelper - UnknownLiteral method. And the default implementation is in CSharpHelperclass.

因此您可以从中派生,覆盖 UnknownLiteral 方法并在那里进行您自己的(预处理)处理:

using Microsoft.EntityFrameworkCore.Design.Internal;

public class MyCSharpHelper : CSharpHelper
{
    public override string UnknownLiteral(object value)
    {
        // Preprocess the value here...
        return base.UnknownLiteral(value);
    }
}

然后用您的服务替换标准服务:

using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.DependencyInjection;

public class MyDesignTimeServices : IDesignTimeServices
{
    public void ConfigureDesignTimeServices(IServiceCollection services)
    {
        services.AddSingleton<ICSharpHelper, MyCSharpHelper>();
    }
}