C# EntityFramework4代码是否首先支持像NHibernate这样的身份生成器?

C# EntityFramework4代码是否首先支持像NHibernate这样的身份生成器?,c#,entity-framework,entity-framework-4,ef-code-first,C#,Entity Framework,Entity Framework 4,Ef Code First,一年前提出的这个问题与此类似: 但我想知道的是,CodeFirstCTP是否增加了对身份生成策略的支持。如果没有,有人知道EF中有一个很好的扩展点来实现类似的东西吗 我目前正在处理使用GUID作为标识符的模型类。使用EF插入时,它们保留其Guid.Empty初始值。我知道您可以将DB中的列的默认值设置为newid(),但这会破坏客户端标识生成的目的 实体框架还不够成熟,不能在分布式、断开连接的系统中使用吗?不,实体框架代码优先仍然是EFv4的良好包装。没有像NHibernate那样的发电机。如

一年前提出的这个问题与此类似:

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

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


实体框架还不够成熟,不能在分布式、断开连接的系统中使用吗?

不,实体框架代码优先仍然是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
}
公共类上下文:DbContext
{
//例如Helper
//不要在真实场景中使用!!!
私有静态int i=0;
公共DbSet myenties{get;private set;}
公共上下文()
:基础(“连接”)
{
MyEntities=Set();
}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
基于模型创建(modelBuilder);
modelBuilder.Entity().HasKey(e=>e.Id);
//关闭数据库中的自动生成
modelBuilder.Entity()
.Property(e=>e.Id)
.HasDatabaseGeneratedOption(HasDatabaseGeneratedOption.None);
//其他映射
}
公共覆盖int SaveChanges()
{
foreach(ChangeTracker.Entries()中的var条目)
.Where(e=>e.State==EntityState.Added))
{
//在这里,您必须添加一些逻辑来生成Id
//我只使用静态场
entry.Entity.Id=++i;
}
返回base.SaveChanges();
}
}
公共类MyEntity
{
公共int Id{get;set;}
//其他属性
}

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

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id {get;set;}
请参阅(第页中EF 4.1:CTRL+F支持的注释的完整列表)

然后使用新的GUID转换字符串

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

EntityFramework4.0是从1.0向前迈出的一大步,但它仍然是另一个不成熟的Microsoft实现。可扩展性几乎没有。@Jeff,虽然我很欣赏你的意见(我的意见类似,我更喜欢NH),但对于这个特定的项目,我没有使用其他东西的余地。很抱歉听到这个消息。我更多地回答了您的问题“实体框架是否还不够成熟,无法在分布式、断开连接的系统中使用?”我的回答是:它已经足够成熟,如果您不介意在分布式系统的每个部分都有一个不成熟的实现。GUI的一个好处是客户端可以分配标识符,而不是等到标识符被持久化到数据库。听起来很有趣,有没有关于如何实现它的指点?(如何获取新实体,如何防止EF分配ID等)@Diego:我添加了一些示例。
Units.Add( new Unit(){Id=Guid.NewGuid().ToString(), Name="123"});