【问题标题】:Does Entity Framework 4 Code First have support for identity generators like NHibernate?Entity Framework 4 Code First 是否支持像 NHibernate 这样的身份生成器?
【发布时间】:2011-07-13 14:47:48
【问题描述】:

一年前提出的这个问题与此类似: Does the Entity Framework 4 support generators for id values like NHibernate?

但我想知道的是,代码优先 CTP 是否增加了对身份生成策略的支持。如果没有,是否有人知道 EF 中有一个很好的扩展点来实现类似的东西?

我目前正在处理使用 GUID 作为标识符的模型类。使用 EF 插入时,它们会保留其 Guid.Empty 初始值。我知道您可以将数据库中列的默认值设置为newid(),但这违背了客户端身份生成的目的。

实体框架是否不够成熟,无法用于分布式、断开连接的系统?

【问题讨论】:

  • EntityFramework 4.0 是从 1.0 向前迈出的一大步,但它仍然是 Microsoft 实现的另一个半成品。可扩展性几乎没有。
  • @Jeff,虽然我很欣赏您的意见(我的意见类似,但我更喜欢 NH),但对于这个特定项目,我没有使用其他东西的余地。
  • 很抱歉听到这个消息。我更多地回答了您的问题“实体框架是否不够成熟,无法在分布式、断开连接的系统中使用?”我对答案的看法是:它已经足够成熟了,如果您不介意在分布式系统的每个部分中实现半成品。
  • GUID 的一个好处是客户端可以分配标识符,而不是等到它被持久化到数据库中。

标签: c# entity-framework entity-framework-4 ef-code-first


【解决方案1】:

不,实体框架代码优先仍然只是 EFv4 的很好的包装器。没有像 NHibernate 这样的生成器。如果您想要客户端 ID 生成器,则必须在派生的 DbContext 中覆盖 SaveChanges 并实现您自己的将 ID 分配给新实体的逻辑。

编辑:

一些高级示例:

public class Context : DbContext
{
    // Helper for example
    // DO NOT USE IN REAL SCENARIOS!!!
    private static int i = 0; 

    public DbSet<MyEntity> MyEntities { get; private set; }

    public Context()
        : base("connection")
    {
        MyEntities = Set<MyEntity>();
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<MyEntity>().HasKey(e => e.Id);
        // Turn off autogeneration in database
        modelBuilder.Entity<MyEntity>()
                    .Property(e => e.Id)
                    .HasDatabaseGeneratedOption(HasDatabaseGeneratedOption.None);

        // Other mapping
    }

    public override int SaveChanges()
    {
        foreach (var entry in ChangeTracker.Entries<MyEntity>()
            .Where(e => e.State == EntityState.Added))
        {
            // Here you have to add some logic to generate Id
            // I'm using just static field
            entry.Entity.Id = ++i;  
        }

        return base.SaveChanges();
    }
}

public class MyEntity
{
    public int Id { get; set; }
    // Other properties
}

【讨论】:

  • 听起来很有趣,关于如何实现它的任何指针? (如何获取新实体,如何防止 EF 分配 Id 等)
  • @Diego:我添加了一些示例。
【解决方案2】:

没有。

Mine Entity Framework 4.1.10715 由 NuGet 安装。 也许你可以使用属性

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id {get;set;}

请参阅(EF 4.1 中支持的注释的完整列表:页面中的 CTRL+F)here

【讨论】:

    【解决方案3】:
    [Key]
    public string Id { get; set; }
    

    然后使用新的 GUID ToString

    Units.Add( new Unit(){Id=Guid.NewGuid().ToString(), Name="123"});
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-18
      • 1970-01-01
      • 2011-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-01
      • 1970-01-01
      相关资源
      最近更新 更多