【发布时间】:2020-04-17 01:56:52
【问题描述】:
我正在尝试覆盖 SQL 迁移生成器的默认行为,以便我可以指定自定义外键约束名称,如 here 所述。我已经按照建议连接了配置。
不幸的是,进展并不顺利。
一个快速的日志语句显示GetFkName() 函数从未被命中。
我尝试了另一种配置结构,如 here 和 here 所讨论的那样,但是当我尝试生成迁移时出现此错误:
在程序集“ConsoleApp1”中发现了多个迁移配置类型。指定要使用的名称。
我觉得这个结果有点奇怪,因为我只有一个配置类、一个 SQL 生成类和一个上下文类(下面的代码没有反映这一点,但我在实际测试中注释掉了额外内容)。在命令行指定配置类型,如here所示,错误如下:
System.InvalidOperationException:“ConsoleApp1.Db.CustomDbConfiguration2”类型不继承自“System.Data.Entity.DbConfiguration”。基于实体框架代码的配置类必须继承自“System.Data.Entity.DbConfiguration”。
所有这一切都让我们回到了here,然后,由于上述原因,这不起作用(GetFkName() 永远不会被击中)。所以看来我在追我的尾巴(直到今天才知道我有一个)。
我应该怎么做才能让这个覆盖正常工作?
配置
Imports System.Data.Entity
Imports System.Data.Entity.Migrations
Imports System.Data.Entity.SqlServer
Namespace Db
Friend Class CustomDbConfiguration
Inherits DbConfiguration
Public Sub New()
Me.SetMigrationSqlGenerator(SqlProviderServices.ProviderInvariantName, Function() New CustomSqlGenerator)
End Sub
End Class
Friend Class CustomDbConfiguration2
Inherits DbMigrationsConfiguration(Of Context)
Public Sub New()
Me.SetSqlGenerator(SqlProviderServices.ProviderInvariantName, New CustomSqlGenerator2(Me.GetSqlGenerator(SqlProviderServices.ProviderInvariantName)))
Me.ContextType = GetType(Context)
End Sub
End Class
End Namespace
SQL 生成器
Imports System.Data.Entity.Migrations.Model
Imports System.Data.Entity.Migrations.Sql
Imports System.Data.Entity.SqlServer
Namespace Db
Friend Class CustomSqlGenerator
Inherits SqlServerMigrationSqlGenerator
Protected Overrides Sub Generate(AddForeignKeyOperation As AddForeignKeyOperation)
AddForeignKeyOperation.Name = GetFkName(AddForeignKeyOperation.PrincipalTable, AddForeignKeyOperation.DependentTable, AddForeignKeyOperation.DependentColumns.ToArray())
MyBase.Generate(AddForeignKeyOperation)
End Sub
Protected Overrides Sub Generate(DropForeignKeyOperation As DropForeignKeyOperation)
DropForeignKeyOperation.Name = GetFkName(DropForeignKeyOperation.PrincipalTable, DropForeignKeyOperation.DependentTable, DropForeignKeyOperation.DependentColumns.ToArray())
MyBase.Generate(DropForeignKeyOperation)
End Sub
Private Shared Function GetFkName(PrimaryKeyTable As String, ForeignKeyTable As String, ParamArray ForeignTableFields As String()) As String
IO.File.WriteAllText("D:\Logs\FkNameTest.log", $"{Now.ToString}{vbCrLf}")
Return $"FK_{ForeignKeyTable}_{PrimaryKeyTable}"
End Function
End Class
Friend Class CustomSqlGenerator2
Inherits MigrationSqlGenerator
Public Sub New(Generator As MigrationSqlGenerator)
Me.Generator = Generator
End Sub
Public Overrides Function Generate(MigrationOperations As IEnumerable(Of MigrationOperation), ProviderManifestToken As String) As IEnumerable(Of MigrationStatement)
Return Me.Generator.Generate(MigrationOperations, ProviderManifestToken)
End Function
Private ReadOnly Generator As MigrationSqlGenerator
End Class
End Namespace
上下文
Imports System.Data.Common
Imports System.Data.Entity
Imports System.Data.SqlClient
Imports System.Reflection
Namespace Db
<DbConfigurationType(GetType(CustomDbConfiguration2))>
Friend Class Context
Inherits DbContext
Public Sub New()
MyBase.New(DbConnection.ConnectionString)
End Sub
Private Sub New(Connection As DbConnection)
MyBase.New(Connection, True)
Database.SetInitializer(New CreateDatabaseIfNotExists(Of Context))
Database.SetInitializer(New MigrateDatabaseToLatestVersion(Of Context, Migrations.Configuration))
Me.Database.Initialize(False)
End Sub
Public Shared Function Create() As Context
Return New Context(DbConnection)
End Function
Private Shared ReadOnly Property DbConnection As SqlConnection
Get
Return New SqlConnection(Utils.DbConnectionString)
End Get
End Property
Protected Overrides Sub OnModelCreating(Builder As DbModelBuilder)
Builder.Configurations.AddFromAssembly(Assembly.GetExecutingAssembly)
MyBase.OnModelCreating(Builder)
End Sub
Public Property Documents As DbSet(Of Document)
Public Property Sections As DbSet(Of Section)
End Class
End Namespace
【问题讨论】:
-
迁移生成后简单修改会更容易。
-
@DavidBrowne-Microsoft 〜谢谢,但如果有几百个'em ;-)
-
@DavidBrowne-Microsoft ~ 你知道怎么做吗?
-
我从来没有这样做过,我也不会在代码优先中尝试这样做。如果您关心外键名称,您可能应该直接在数据库中维护您的架构,然后从中逆向工程 EF 模型。
-
@DavidBrowne-Microsoft ~ 明白了,谢谢。
标签: vb.net entity-framework-6 ef-code-first entity-framework-migrations