我首先使用代码(EntityFramework 6.1)和Table Per Concrete类型方法。
根据此thread的最后一条评论,EF 6.1未在上设置SQL自动增量Identity
。我明白了。
但我想在上强制执行此Identity
,因为我永远不会使用(也不会定义)基类DbSet<>
。我不会访问基类集合,只访问具体的集合。
更多的话,一些代码:
public abstract class BaseModel
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)] // <- tried to force it, but does not work
public long Id { get; set; }
[Timestamp]
public byte[] DataVersion { get; set; }
public string CreatedWho { get; set; }
public DateTime CreatedWhen { get; set; }
public string UpdatedWho { get; set; }
public DateTime UpdatedWhen { get; set; }
}
public class Currency : BaseModel
{
public string IsoCode {get; set; }
}
在我的DbContext
课程中有:
public DbSet<Currency> Currencies {get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Enable TPC Inheritance
modelBuilder.Entity<Currency>().Map(m =>
{
m.MapInheritedProperties();
m.ToTable(typeof(Currency).Name);
});
base.OnModelCreating(modelBuilder);
}
使用此代码,在我生成的数据库表Currency
中,我按预期拥有所有BaseModel
列,Id
是主键,确定。但是,尽管使用了明确的Identity
属性,但上没有DatabaseGenerated
属性集。
如何在TPC继承架构中强制Identity
?
答案 0 :(得分:1)
标识列是每个表,TPC每个类有一个表,没有共享基类表,它将保存标识生成的id。如果您具有生成标识的具体类型表作为id,则将在这些表中获得重复的ID。
可以找到对此问题的讨论,例如here,此部分涉及此特定问题:
如何解决TPC中的身份问题
如您所见,使用SQL Server的int标识列并不能正常工作 与TPC一起使用,因为当时会有重复的实体键 在子类表中插入所有具有相同标识种子的表。 因此,要解决这个问题,要么是传播种子(每个表都有) 将需要它自己的初始种子值),或者除了它之外的其他机制 应该使用SQL Server的int标识。其他一些RDBMS有 允许序列(身份)共享的其他机制 使用GUID键可以实现多个表和类似的东西 在SQL Server中。使用GUID键或int身份键时 不同的起始种子将解决问题但另一个 解决方案是完全关闭主键上的身份 属性。因此,我们需要承担提供的责任 将记录插入数据库时的唯一键。我们会一起去的 这个解决方案,因为它无论哪个数据库引擎都适用 使用
答案 1 :(得分:0)
似乎[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
最终会在TPC inhertiance上下文中强制我的PK上的Identity行为。
诀窍?软件包控制台命令Update-Databse -Force
执行不自动应用该类别的更改。您需要删除表格以重新创建它们。
我使用以下SQL脚本删除所有内容(甚至__MigrationHistory
),灵感来自this blog:
WHILE ( EXISTS ( SELECT 1
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE CONSTRAINT_TYPE = 'FOREIGN KEY' ) )
BEGIN
DECLARE @sql NVARCHAR(2000)
SELECT TOP 1
@sql = ( 'ALTER TABLE ' + TABLE_SCHEMA + '.[' + TABLE_NAME
+ '] DROP CONSTRAINT [' + CONSTRAINT_NAME + ']' )
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE CONSTRAINT_TYPE = 'FOREIGN KEY'
EXEC (@sql)
PRINT @sql
END
GO
WHILE ( EXISTS ( SELECT 1
FROM INFORMATION_SCHEMA.TABLES ) )
BEGIN
DECLARE @sql NVARCHAR(2000)
SELECT TOP 1
@sql = ( 'DROP TABLE ' + TABLE_SCHEMA + '.[' + TABLE_NAME
+ ']' )
FROM INFORMATION_SCHEMA.TABLES
EXEC (@sql)
PRINT @sql
END
之后,重新运行Update-Database -Force
命令以重新生成所有表。 Identity
将被激活。