首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TPC -标识主键

TPC -标识主键
EN

Stack Overflow用户
提问于 2015-04-09 10:19:05
回答 2查看 1.4K关注 0票数 0

我使用的是代码优先(EntityFramework 6.1)和每种具体类型的表方法。

根据这个线程的最后一个注释,EF6.1没有将SQL自动增量Identity设置为on。我能理解。

但是我想强制使用这个Identity,因为我永远不会使用(也不会定义)基类DbSet<>。我不会访问基类集合,只访问具体的类集合。

更多的话,一些代码:

代码语言:javascript
复制
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类中,有:

代码语言:javascript
复制
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);
}

使用这段代码,在我生成的DB表Currency中,所有的BaseModel列都如预期的那样,Id是主键,ok。但是它没有设置Identity属性,尽管使用了DatabaseGenerated属性。

如何在TPC继承模式中强制使用Identity

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-04-10 08:33:30

似乎[DatabaseGenerated(DatabaseGeneratedOption.Identity)]最终会在TPC继承上下文中强制我的PK上的身份行为。

诀窍?包控制台命令Update-Databse -Force执行而不是自动应用该类型的更改。您需要移除您的表,以重新创建它们的所有新鲜。

我使用下面的SQL脚本来删除所有内容(甚至是__MigrationHistory),这是受这个博客启发的:

代码语言:javascript
复制
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将被激活。

票数 0
EN

Stack Overflow用户

发布于 2015-04-09 10:27:05

每个表都有标识列,TPC每个类都有一个表,没有一个共享基类表可以保存标识生成的id。如果将具体类型的表生成标识为id,则将在这些表中获得重复的id。

对这一问题的讨论可以找到,例如这里,本部分涉及这一具体问题:

如何解决TPC中的身份问题 正如您所看到的,使用SQL Server的int标识列与TPC一起工作并不太好,因为当插入具有相同标识种子的子类表时会出现重复的实体键。因此,要解决这个问题,需要一个扩展种子(每个表都有自己的初始种子值),或者使用SQL Server的int标识以外的机制。其他一些RDBMSes具有允许多个表共享序列(标识)的其他机制,并且可以使用Server中的GUID键实现类似的功能。虽然使用GUID键或具有不同启动种子的int标识键可以解决问题,但另一种解决方案是完全关闭主键属性上的标识。因此,在向数据库插入记录时,我们需要承担提供唯一密钥的责任。我们将使用这个解决方案,因为不管使用的是哪个数据库引擎,它都能工作。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29535791

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档