注意:用 VB.NET 或 C# 回答都可以。我没有偏好。
我正在使用每种类型一个表的架构。
我希望我的所有实体都有第二个键列(类型为
Guid
),所以我创建了一个像这样的基类:
Public MustInherit Class Entity
Public Property Id As Integer
Public Property Key As Guid
End Class
Public Class City
Inherits Entity
Public Property Name As Integer
Public Property Code As String
End Class
我希望添加新行时,这些列中的每一列都能在数据库级别(SQL Server)自动填充,因此我创建了如下配置:
Public Class EntityConfiguration
Implements IEntityTypeConfiguration(Of Entity)
Public Sub Configure(Builder As EntityTypeBuilder(Of Entity)) Implements IEntityTypeConfiguration(Of Entity).Configure
Builder.Property(Function(Entity) Entity.Key).IsRequired.HasDefaultValueSql("NEWID()")
End Sub
End Class
这有效 - 列已正确添加 - 但迁移生成器仅为一个表构建代码,名为
Entities
。
我在我的
CityConfiguration
课上尝试过这个:
Builder.ToTable("Cities")
...但是生成器仍然包含一个
Entity
表。由于显而易见的原因,这是不希望的。 Entity
只是一个基类。并且 Key
表中省略了 Cities
列。
有没有办法让我的所有实体都包含这个公共
Key
列,而不必在每个实体的配置中包含对 HasDefaultValueSql("NEWID()")
的显式调用?这将是乏味且容易出错的。
嗯,糟糕……没花很长时间。
一个快速而肮脏的扩展方法可以很好地帮助我们实现目标:
Public Module Extensions
<Extension>
Public Sub AddKey(Of TEntity As Entity)(Builder As EntityTypeBuilder(Of TEntity))
Builder.Property(Function(Entity) Entity.Key).IsRequired.HasDefaultValueSql("NEWID()")
Builder.HasIndex(Function(Entity) Entity.Key).IsUnique()
End Sub
End Module
然后我们在每个实体的配置中这样称呼它:
Builder.AddKey
如果有人想使用这个想法,我将保留此问答。
--编辑--
使用基类可能更干净:
Public MustInherit Class BaseConfiguration(Of T As Entity)
Public Overridable Sub Configure(Builder As EntityTypeBuilder(Of T))
Builder.Property(Function(Entity) Entity.Key).IsRequired.HasDefaultValueSql("NEWID()")
Builder.HasIndex(Function(Entity) Entity.Key).IsUnique()
End Sub
End Class
只需确保它没有实现
IEntityTypeConfiguration(Of Entity)
,否则将会生成不需要的 Entity
表。
像这样使用它:
Public Class CityConfiguration
Inherits BaseConfiguration(Of City)
Implements IEntityTypeConfiguration(Of City)
Public Overrides Sub Configure(Builder As EntityTypeBuilder(Of City)) Implements IEntityTypeConfiguration(Of City).Configure
Builder.Property(Function(City) City.Code).IsRequired.HasDefaultValue(String.Empty).HasMaxLength(7)
Builder.Property(Function(City) City.Name).IsRequired.HasDefaultValue(String.Empty).HasMaxLength(25)
Builder.HasIndex(Function(City) City.Code).IsUnique()
Builder.HasIndex(Function(City) City.Name)
MyBase.Configure(Builder)
End Sub
End Class