Как добавить поддержку структурированных аннотаций в построитель целей EF Core SqlServer?
Легко добавить простые строковые аннотации к модели EF с HasAnnotation
метод, который принимает object
тип аргумента, но при попытке добавить структурированные аннотации вы получите ошибки при миграции сборки:
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
что поможет сериализовать структурированные аннотации?
Зачем мне это нужно? Просто пытаюсь собрать всю базу метаданных в одном месте. А мета это обычно структурированная информация.
1 ответ
Насколько я понимаю (информации об этом немного, если вообще есть), идея в том, чтобы использовать простые пары имя / значение, где значения являются примитивными типами (string
, int
, decimal
, DateTime
и т. д. плюс enum
s) и имена образуют структуру. Все аннотации EF Core следуют этому принципу. Например, Имя: "SqlServer:ValueGenerationStrategy"
Тип: SqlServerValueGenerationStrategy
и т.п.
Вероятно, проще всего просто следовать этой конвенции. Но в любом случае, ответственная служба ICSharpHelper
- UnknownLiteral
метод. И реализация по умолчанию находится в CSharpHelper
учебный класс.
Таким образом, вы можете извлечь из него, переопределить 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>();
}
}