Entity Framework 4 Code First是否支持像NHibernate这样的身份生成器?

11
这是一个在一年前提出的类似问题: Entity Framework 4是否支持像NHibernate一样的ID生成器? 但我想知道的是,如果Code First CTP增加了对标识生成策略的支持。如果没有,有没有人知道在EF中实现类似功能的好扩展点?
我目前正在使用将GUID用作标识符的模型类。当使用EF插入时,它们保留其Guid.Empty初始值。我知道可以为DB中的列设置默认值newid(),但这会破坏客户端标识生成的目的。
Entity Framework是否成熟到足以用于分布式、断开连接的系统中?

4
EntityFramework 4.0是从1.0迈出的一大步,但它仍然是另一个未完善的微软实现。其可扩展性点寥寥无几。 - Jeff
1
@Jeff,虽然我欣赏你的意见(我的看法也类似,我更喜欢NH),但对于这个特定的项目,我没有使用其他东西的余地。 - joshperry
很遗憾听到这个。我更多地是在回答你的问题“Entity Framework在一个分布式、断开连接的系统中是否不够成熟?”我的理解是:它已经足够成熟了,只要你不介意在分布式系统的各个部分中有一些不完善的实现。 - Jeff
GUID的一个好处是客户端可以分配标识符,而不必等待其持久化到数据库中。 - Brian Low
3个回答

16
不,Entity Framework Code-First 仍然只是 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分配Ids等) - Diego Mijelshon
6
@Diego:我添加了一些例子。 - Ladislav Mrnka

6

我的 NuGet 安装了实体框架 4.1.10715。 也许你可以使用属性。

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

请查看(EF 4.1支持的完整注释列表:在页面中使用CTRL + F)此处

-1
[Key]
public string Id { get; set; }

然后使用新的 GUID ToString

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接