实体框架代码首先使用GUID作为标识与另一标识列(Entity Framework Code Fir

2019-06-17 19:00发布

又名我们如何创造的Code First多重身份列?

因为聚类性能的,常见的建议是使用自动递增的整数列,而不是用创建的GUID的newid()

为了声明一个列自动增量,你必须与注释指定它[DatabaseGenerated(DatabaseGeneratedOption.Identity)]

但是,你只能有一个表中的身份。

于是开始了基础模型,如:

public abstract class ModelBase {
    // the primary key
    public virtual Guid Id { get; set; }

    // a unique autoincrementing key
    public virtual int ClusterId { get; set; }
}

我们如何来设置它,因此:

  1. GUID是由数据库,而不是码自动生成
  2. ClusterId是自动增量
  3. 实体框架代码首先不抛出各种类似的错误:
    • 修改表的其中一个主键列具有属性“StoreGeneratedPattern”设置为“计算”不被支持。 使用“身份”而不是模式。

仅供参考 ,如果你想在代码自动生成它,你可以跳过ID字段中的注释,并做一些事情,如:

public abstract class AbstractContext : DbContext {

  /// <summary>
  /// Custom processing when saving entities in changetracker
  /// </summary>
  /// <returns></returns>
  public override int SaveChanges()
  {
      // recommended to explicitly set New Guid for appropriate entities -- http://msdn.microsoft.com/en-us/library/dd283139.aspx
      foreach (var entry in ChangeTracker.Entries<ModelBase>().Where(e => e.State == EntityState.Added) ) {

          // only generate if property isn't identity...
          Type t = entry.Entity.GetType();
          var info = t.GetProperty("Id").GetCustomAttributes(
              typeof(DatabaseGeneratedAttribute), true).Cast<DatabaseGeneratedAttribute>().Single();

          if (info.DatabaseGeneratedOption != DatabaseGeneratedOption.Identity) {
              entry.Entity.Id = Guid.NewGuid(); // now we make it
          }
      }
      return base.SaveChanges();
  }

}

Answer 1:

这结束了工作对我来说,实体框架5。

  1. 关闭自动迁移
  2. 迁移到创建初始表,没有多余的装饰
  3. 声明ClusterId为标识(注释)

     [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public override int ClusterId { get; set; } 
  4. 迁移

  5. 声明PK属性Id作为身份的另一种更新后

     [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public override Guid Id { get; set; } 
    • 奖金 :EF似乎假定Id是主键,所以你不需要[Key, Required]
  6. 像创建迁移代码add-migration TrickEfIntoAutogeneratingMultipleColumns

  7. Up()方法,在AlterColumn声明,告诉数据库通过声明来自动生成的GUID defaultSqlValue
    • AlterColumn(theTable, "Id", c => c.Guid(nullable: false, identity: true, defaultValueSql: "newid()"));
  8. 迁移

这似乎是“绝招” EF,在某种意义上说,它假定两列是身份和相应地做出反应。 在迁移过程中,它试图让另一列的身份,但似乎并不在意时默默失败 - 你最终有一个标记为身份和其他用默认值。

在正常的代码运行,当EF穿过的SaveChanges / ChangeTracking步骤,因为它看到了Id属性作为身份确实是整个“指定临时密钥”的事情 ,因此,它不是试图使用默认的0000000 ...值,而是让数据库使用指定的默认值函数生成它。

(我还以为这个注释字段作为Computed就完成了同样的事情,但是...我在问题中提到的错误...唉...)

而且,因为ClusterId字段也是在代码中的身份,真的是在数据库中的身份,它自动递增为好。



文章来源: Entity Framework Code First Using Guid as Identity with another Identity Column