0

我使用 Guids 作为数据库中实体的主键,当我使用实体框架 5 在数据库中插入记录时使用 asp.net 4.5 Web 表单的模型绑定功能,我正在做类似的事情

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();
4

1 回答 1

1

您可以尝试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();

    //...
于 2013-05-25T15:57:58.993 回答