gpt4 book ai didi

c# - 如何在 EF Core Code First 中自定义迁移生成?

转载 作者:行者123 更新时间:2023-12-03 20:24:42 27 4
gpt4 key购买 nike

我的 DbContext 中有一个特殊的基表类型.当从它继承时,我需要生成一个额外的“SQL”迁移操作来为它创建一个特定的触发器。它通过检查重叠范围来确保表结构是一致的。由于 SQL Server 中没有重叠的索引或检查约束,我必须使用触发器(在检查约束中使用函数会导致与迁移相同的问题以及 SQL 中的杂乱函数“命名空间”)。
因为我在 OnModelCreating 期间没有找到任何创建触发器的方法。我想改变生成的迁移。但是怎么做呢?
尝试使用 SqlServerMigrationsSqlGeneratorSqlServerMigrationsAnnotationProvider ,但顾名思义,它们仅用于最后阶段,即在生成 SQL 命令期间。这使得它们在使用迁移时有点“隐藏”。难以在需要时进行定制并在事后进行维护。
考虑使用CSharpMigrationOperationGenerator这似乎非常适合我的需求。但是有一个问题——我不能访问这个类。也不是 namespace 。
根据消息来源,此类位于 Microsoft.EntityFrameworkCore.Migrations.Design命名空间并且是公共(public)的。为了访问它 Microsoft.EntityFrameworkCore.Design必须安装包。
但它不起作用。
我在这里想念什么?如何访问和继承这个类?或者,在迁移特定表的过程中,是否有更好、更合适的方法来自动创建触发器?

最佳答案

如何提供自己的ICSharpMigrationOperationGenerator执行

Thought about using CSharpMigrationOperationGenerator which seems to be perfect for my needs. But there is a problem - I can't access this class. Nor it's namespace.

According to source this class resides in Microsoft.EntityFrameworkCore.Migrations.Design namespace and is public. And in order to access it a Microsoft.EntityFrameworkCore.Design package has to be installed.

But it doesn't work.

What am I missing here? How to access and inherit this class?


假设您在设计时调用以下 CLI 命令来添加新迁移:
dotnet ef migrations add "SomeMigration"
这是一个完整的示例控制台程序,它将使用自定义 ICSharpMigrationOperationGenerator实现称为 MyCSharpMigrationOperationGenerator , 继承自 CSharpMigrationOperationGenerator :
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Migrations.Design;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace IssueConsoleTemplate
{
public class MyCSharpMigrationOperationGenerator : CSharpMigrationOperationGenerator
{
public MyCSharpMigrationOperationGenerator(CSharpMigrationOperationGeneratorDependencies dependencies)
: base(dependencies)
{
}

protected override void Generate(CreateTableOperation operation, IndentedStringBuilder builder)
{
Console.WriteLine("\r\n\r\n---\r\nMyCSharpMigrationOperationGenerator was used\r\n---\r\n");
base.Generate(operation, builder);
}
}

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

public class IceCream
{
public int IceCreamId { get; set; }
public string Name { get; set; }
}

public class Context : DbContext
{
public DbSet<IceCream> IceCreams { get; set; }

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseSqlServer(@"Data Source=.\MSSQL14;Integrated Security=SSPI;Initial Catalog=So63575132")
.UseLoggerFactory(
LoggerFactory.Create(
b => b
.AddConsole()
.AddFilter(level => level >= LogLevel.Information)))
.EnableSensitiveDataLogging()
.EnableDetailedErrors();
}
}

internal static class Program
{
private static void Main()
{
}
}
}
MyCSharpMigrationOperationGenerator类为每个添加的表输出以下行,以证明它被调用:
---
MyCSharpMigrationOperationGenerator was used
---
正如@KasbolatKumakhov 在他的评论中指出的那样,还应该指出引用 Microsoft.EntityFrameworkCore.Design 的方式 has been changed从 2.2.到 3.0:

Starting with EF Core 3.0, it is a DevelopmentDependency package. This means that the dependency won't flow transitively into other projects, and that you can no longer, by default, reference its assembly.[...]If you need to reference this package to override EF Core's design-time behavior, then you can update PackageReference item metadata in your project.

<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.0.0">
<PrivateAssets>all</PrivateAssets>
<!-- Remove IncludeAssets to allow compiling against the assembly -->
<!--<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>-->
</PackageReference>

如何正确实现附加 MigrationOperation (例如,用于创建触发器)

Since I haven't found any way to create triggers during OnModelCreating I thought of altering generated migrations. But how to do that?


要正确执行此操作,您需要执行以下操作:
  • 将您自己的注释添加到相关表中(例如 MyPrefix:Trigger )
  • 实现你自己的MigrationOperation (例如 CreateTriggerMigrationOperation )
  • 提供您自己的IMigrationsModelDiffer返回您自己的 MigrationsModelDiffer 的实现(源自 MigrationOperation ;这是内部的)
  • 提供您自己的ICSharpMigrationOperationGenerator实现(派生自 CSharpMigrationOperationGenerator ),然后为您自己的 MigrationOperation 生成 C# 代码
  • 提供您自己的IMigrationsSqlGenerator实现(源自 SqlServerMigrationsSqlGenerator ),然后处理翻译您自己的 MigrationOperation转 SQL
  • 关于c# - 如何在 EF Core Code First 中自定义迁移生成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63575132/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com