C# EntityFramework4代码是否首先支持像NHibernate这样的身份生成器?
一年前提出的这个问题与此类似: 但我想知道的是,CodeFirstCTP是否增加了对身份生成策略的支持。如果没有,有人知道EF中有一个很好的扩展点来实现类似的东西吗 我目前正在处理使用GUID作为标识符的模型类。使用EF插入时,它们保留其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那样的发电机。如
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"});