gpt4 book ai didi

entity-framework - Entity Framework 代码首先使用 Guid 作为身份与另一个身份列

转载 作者:行者123 更新时间:2023-12-03 07:41:45 26 4
gpt4 key购买 nike

a.k.a我们如何在 Code First 中创建多个标识列?

考虑到集群性能,通常建议使用自动增量整数列,而不是使用 newid() 创建的 GUID。

为了将列声明为自动增量,您必须使用注释[DatabaseGenerate(DatabaseGenerateOption.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. Entity Framework Code First 不会抛出各种错误,例如:
    • 不支持对主键列的属性“StoreGeneratePattern”设置为“计算”的表进行修改。请改用“身份”模式。
<小时/>

仅供引用,如果您确实想在代码中自动生成它,您可以跳过 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 Framework 5。

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

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

  5. 在更新另一个 pk 属性 Id 后将其声明为 Identity

    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public override Guid Id { get; set; }
    • 奖励:EF 似乎假设 Id 是主键,因此您不需要 [Key, required]
  6. 创建迁移代码,例如 add-migration TrickEfIntoAutogenerateMultipleColumns

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

这似乎“欺骗”了 EF,因为它假设两列都是身份并做出相应的 react 。在迁移过程中,它尝试将另一列设置为身份,但似乎并不关心何时默默失败 - 最终您会得到一个标记为身份的列,而另一列则带有默认值。

在正常代码操作期间,当 EF 执行 SaveChanges/ChangeTracking 步骤时,因为它将 Id 属性视为一个 Identity,所以它是整个 "assign temporary key" thing ,这样它就不会尝试使用默认的 0000000... 值,而是让数据库使用您指定的默认值函数生成它。

(我本以为将此字段注释为 Compulated 会完成同样的事情,但是...我在问题中提到的错误...嘘...)

而且,由于 ClusterId 字段也是代码中的一个 Identity,而且实际上也是数据库中的一个 Identity,因此它也会自动递增。

关于entity-framework - Entity Framework 代码首先使用 Guid 作为身份与另一个身份列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12012736/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com