【问题标题】:How to add custom data to an EF Core model during OnModelCreating?如何在 OnModelCreating 期间将自定义数据添加到 EF Core 模型?
【发布时间】:2022-06-25 02:57:11
【问题描述】:

我正在尝试编写一个在模型构建阶段执行一些额外检查的方法,然后在模型中存储一个自定义对象CustomInfoModel,以便稍后在需要时将其拉出。

CustomInfoModel 包含特定于模型本身的数据,因此我不想在每次创建 DbContext 时都构建它。

所以我的想法是在ModelBuilder 上创建一个扩展方法并从OnModelBuilding 调用它。似乎注解是存储此对象的最佳方式,因此我创建了该对象,将其存储为注解,然后调用Ignore,这样它就不会被使用:

public void AddCustomInfoModel(this ModelBuilder modelBuilder)
{
    var customModel = CustomInfoModel.FromBuilder(modelBuilder);
    modelBuilder.HasAnnotation(nameof(CustomInfoModel), customModel);
    modelBuilder.Ignore<CustomInfoModel>();
}

这似乎工作正常;我以后可以在需要时使用Model.FindAnnotation() 检索此对象。但是,当尝试使用 dotnet ef migrations add 添加迁移时,我收到以下错误:

System.InvalidOperationException: Cannot scaffold C# literals of type 'MyApp.CustomInfoModel'. 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.Design.Internal.CSharpHelper.Fragment(MethodCallCodeFragment fragment, Boolean typeQualified, String instanceIdentifier, Int32 indent)
   at Microsoft.EntityFrameworkCore.Design.Internal.CSharpHelper.Fragment(MethodCallCodeFragment fragment, String instanceIdentifier, Boolean typeQualified)
   at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpSnapshotGenerator.GenerateAnnotations(String builderName, IAnnotatable annotatable, IndentedStringBuilder stringBuilder, Dictionary`2 annotations, Boolean inChainedCall, Boolean leadingNewline)
   at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpSnapshotGenerator.Generate(String modelBuilderName, 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_0`1.<Execute>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
Cannot scaffold C# literals of type 'MyApp.CustomInfoModel'. The provider should implement CoreTypeMapping.GenerateCodeLiteral to support using it at design time.

所以我的问题是:有没有办法隐藏这个注释,让数据库提供者完全忽略它?或者有没有更好的方法在模型中存储“额外”数据,这些数据只创建一次,然后可供所有未来的DbContext 实例使用?

【问题讨论】:

    标签: c# entity-framework-core entity-framework-migrations


    【解决方案1】:

    从代码优先的角度来看,docs 通过实现 IMigrationsSqlGenerator 的替换服务来说明类似的自定义示例,该服务扩展了您计划用于部署的任何特定于提供商的实现。也就是说,您将获得一个覆盖方法,用于微调给定提供程序对您的自定义数据/操作的处理。

    也许您可以检查 EF Core 源代码以查找允许您自定义脚手架迁移过程的脚手架对应项?或者在他们的 GitHub 上打开一个问题(他们似乎反应灵敏)。

    很抱歉,我无法提供更多帮助。

    【讨论】:

      猜你喜欢
      • 2018-07-28
      • 1970-01-01
      • 1970-01-01
      • 2014-04-02
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      • 2020-02-10
      • 1970-01-01
      相关资源
      最近更新 更多