【问题标题】:Non Clustered Primary Key Entity Framework Code First非聚集主键实体框架代码优先
【发布时间】:2016-10-17 17:25:42
【问题描述】:

在Entity Framework Code First方法中,我们可以将主键定义为非聚集索引,并将其他几个字段的组合定义为聚集索引。

谢谢

【问题讨论】:

    标签: indexing entity-framework-6


    【解决方案1】:

    Radenko Zecanswer 在 EF Core 中也非常有用。我将在此基础上提供一个完整的解决方案来控制命名,并在需要时包括一个身份。我将从我的一个项目中选择一个示例:

    NLog

    NLogId - Primary Key, non-clustered, identity
    EnteredDate - Clustered index
    <other columns>
    

    在 EF Core 中,您需要:

    1. 使用[Key]属性修饰NLogId属性
    2. 使用 db context OnModelCreating 覆盖自定义您的密钥:

      entity
          .HasKey(p => p.NlogId)
          .ForSqlServerIsClustered(false).HasName("PK_NLog");
      
      entity
          .HasIndex(p => p.EnteredDate)
          .ForSqlServerIsClustered(true).HasName("IDX_NLog_EnteredDate");
      
    3. 仔细检查是否生成了身份代码(之后添加身份更难):

      migrationBuilder.CreateTable(
          name: "NLog",
          columns: table => new
          {
              NLogId = table.Column<int>(nullable: false)
                  .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
      

    【讨论】:

      【解决方案2】:

      EF 6.2 解决了这个问题。目前,它处于测试状态,但它可以工作。

      首先,将您的 EF 升级到 6.2:

      Install-Package EntityFramework -Version 6.2.0-beta1 -Pre
      

      然后,在 OnModelCreating 方法中,将主键的 IsClustered 设置为 false

      modelBuilder.Entity<Receipt>().HasKey(r => r.RecId, config => config.IsClustered(false) );
      

      【讨论】:

      • 6.2.0 版现在是最终版,不再是测试版。这个答案很完美。我从 6.1.3 更新到 6.2.0 只是为了做到这一点并且没有任何问题。 +1
      【解决方案3】:

      Entity Framework Core Code First 有一个解决方案,方法是在 DbContext 中覆盖 OnModelCreating

        p.HasKey(b => b.ColumnId).ForSqlServerIsClustered(false);
      

      此代码将生成如下迁移:

       table.PrimaryKey("PK_Columns", x => x.ColumnId)
                              .Annotation("SqlServer:Clustered", false);
      

      【讨论】:

        【解决方案4】:

        EntityTypeConfiguration 不提供将主键设置为非聚集索引的方法,但您可以通过更改用于创建表的初始迁移来完成此操作。有一个例子here

        以下是如何使用属性指定聚集多列索引的示例:

        [Index("IX_ColumnOneTwo", 1, IsClustered = true)]
        public int ColumnOne { get; set;}
        
        [Index("IX_ColumnOneTwo", 2, IsClustered = true)]
        public int ColumnTwo { get; set; }
        

        以及如何使用模型构建器完成此操作的示例:

        modelBuilder.Entity<ClassOne>() 
                    .Property(t => t.ColumnOne) 
                    .HasColumnAnnotation( 
                             "Index",  
                             new IndexAnnotation(new IndexAttribute("IX_ColumnOneTwo") { IsClustered = true }));
        modelBuilder.Entity<ClassOne>() 
                    .Property(t => t.ColumnTwo) 
                    .HasColumnAnnotation( 
                             "Index",  
                             new IndexAnnotation(new IndexAttribute("IX_ColumnOneTwo") { IsClustered = true }));
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-01-15
          • 1970-01-01
          • 1970-01-01
          • 2012-03-04
          • 2011-08-05
          相关资源
          最近更新 更多