entity framework代码首先将Guid用作另一个标识列的标识
又如何在Code First中创build多个标识列?
由于集群性能,常见的build议是使用自动增量整数列而不是使用newid()
创build的GUID。
为了将列声明为自动增量,必须使用Annotation [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; } }
我们如何设置它以便:
- Guid是由数据库自动生成的,而不是代码
-
ClusterId
是自动增量的 - entity framework代码首先不会抛出各种类似的错误:
- 不支持将主键列的属性“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(); } }
这最终为我工作,entity framework5。
- closures自动迁移
- 迁移到创build初始表,没有装饰
-
将
ClusterId
声明为标识(注释)[DatabaseGenerated(DatabaseGeneratedOption.Identity)] public override int ClusterId { get; set; }
-
迁移
-
另一个更新后,将pk属性
Id
声明为Identity[DatabaseGenerated(DatabaseGeneratedOption.Identity)] public override Guid Id { get; set; }
- 奖金 :EF似乎认为
Id
是主键,所以你不需要[Key, Required]
- 奖金 :EF似乎认为
-
像
add-migration TrickEfIntoAutogeneratingMultipleColumns
一样创build迁移代码 - 在
Up()
方法中,在AlterColumn
语句中,通过声明defaultSqlValue
来通知数据库自动生成GUID-
AlterColumn(theTable, "Id", c => c.Guid(nullable: false, identity: true, defaultValueSql: "newid()"));
-
- 迁移
这似乎“欺骗”了EF,因为它假设两列都是身份,并作出相应的反应。 在迁移过程中,它会尝试使另一个列成为一个标识,但是看起来并不在意,当它悄无声息地失败时 – 最终会有一个标识为标识,另一个标识为缺省值。
在正常的代码操作期间,当EF经历SaveChanges / ChangeTracking步骤时,因为它将Id
属性看作是Identity,它完全是“分配临时密钥” ,所以它不会尝试使用默认的0000000 …值,而是让数据库使用您指定的默认值函数来生成它。
(我会认为注释这个领域作为Computed
会完成相同的事情,但…我在问题中提到的错误…嘘…)
而且,因为ClusterId
字段也是代码中的标识,并且实际上是数据库中的标识,所以它也自动增量。