我使用Guids作为主键在我的数据库中的实体,使用asp.net 4.5 web表单的模型绑定功能,当我插入一个记录在数据库中使用实体框架5我做的事情像
public void onInsert([Control("ControlID")] int? countryID){
if(countryID.hasValue){
var DbEntityToInsert = new DbEntity(); //where DbEntity is the class generated by the EF
TryUpdateModel(DbEntityToInsert);
DbEntityToInsert.GuidPK = Guid.NewGuid();
if(Page.ModelState.IsValid){
using(var db = new DatabaseContext()){
db.Add(DbEntityToInsert);
db.Save();
}//using ends
}//modelstate.isvalid if ends
}//countryid.hasvalue ends
}//main method ends
现在我想问是否有一种方法可以告诉EF在插入新记录时为PK生成一个Guid,这样我就不必写
行了 DbEntityToInsert.GuidPK = Guid.NewGuid();
您可以尝试在派生上下文中重写SaveChanges
。主要任务是找出一个实体是否有GuidPK
属性作为主键。下面是使用反射的尝试:
public override int SaveChanges()
{
this.ChangeTracker.DetectChanges();
var addedEntities = this.ChangeTracker.Entries()
.Where(e => e.State == EntityState.Added)
.Select(e => new
{
Entity = e.Entity,
PropertyInfo = e.Entity.GetType().GetProperty("GuidPK")
})
.Where(x => x.PropertyInfo != null && x.PropertyInfo.CanWrite);
foreach (var x in addedEntities)
x.PropertyInfo.SetValue(x.Entity, Guid.NewGuid());
return base.SaveChanges();
}
为了避免这里的反射,你可以有一个共同的接口,由所有使用GuidPK
属性作为PK的实体实现:
public interface IEntityWithGuidPK
{
Guid GuidPK { get; set; }
}
public class DbEntity : IEntityWithGuidPK
{
public Guid GuidPK { get; set; }
// ...
}
则SaveChanges
中的代码为:
//...
var addedEntities = this.ChangeTracker.Entries()
.Where(e => e.State == EntityState.Added &&
e.Entity is IEntityWithGuidPK)
.Select(e => e.Entity as IEntityWithGuidPK);
foreach (var e in addedEntities)
e.GuidPK = Guid.NewGuid();
//...