在上下文之前获取新创建实体的数据库ID(IDENTITY COLUMN).SaveChanges()



是否可以使用实体框架为数据库中要添加的行保留IDENTITY值?

在我对ObjectContext.SaveChanges的覆盖中,我想做这样的事情:

public override int SaveChanges(SaveOptions options)
{
    var affectedEntities = ObjectStateManager.GetObjectStateEntries(
        EntityState.Added |
        EntityState.Modified |
        EntityState.Deleted);
    foreach (var entry in affectedEntities)
    {
        var type = GetObjectType(entry.Entity.GetType());
        if (entry.State == EntityState.Added)
        {
            // log the creation of the new entity into a log file
            // or a different table. For this, I need the newly
            // created entity's ID. Is it possible?
        }
    }
    return base.SaveChanges(options);
    // if I check for ObjectState here, i.e. after SaveChanges, 
    // it won't work? Because once the changes are committed to the database
    // the newly added object's state would no longer remain
    // Added.
}

您不能要求数据库预先分配id。你有两个选项

  1. 实现您自己的身份服务器
  2. 将数据写入数据库后获取id

下面是选项2的几个例子。它们都做同样的事情——在调用SaveChanges()之前构建一个添加项的列表,然后对其进行迭代。

public interface IIDentifiable
{
    int id { get; set; }
}
public override int SaveChanges()
{
    ChangeTracker.DetectChanges();
    List<IIDentifiable> addedObjects = GetNewEntries();
    int result = base.SaveChanges();
    foreach (IIDentifiable o in addedObjects)
    {
        //log o.id
    }
    return result;
}
private List<IIDentifiable> GetNewEntries()
{
    var result = (
        from e in ChangeTracker.Entries()
        where e.State == System.Data.EntityState.Added
        select e.Entity)
        .OfType<IIDentifiable>()
        .ToList();
    return result;
}

CCD_ 3的缺点是获得诸如CCD_

第二种选择是做同样的事情,但使用dynamic而不是IIDentifiable

public override int SaveChanges()
{
    ChangeTracker.DetectChanges();
    List<dynamic> addedObjects = GetNewEntries();
    int result = base.SaveChanges();
    foreach (dynamic o in addedObjects)
    {
        //log o.id
        //log o.GetType()
    }
    return result;
}
private List<dynamic> GetNewEntries()
{
    var result = (
        from e in ChangeTracker.Entries()
        where e.State == System.Data.EntityState.Added
        select e.Entity)
        .ToList();
    return result;
}

最新更新