将尚未分配的ID分配给新实体

时间:2015-07-23 16:09:18

标签: c# entity-framework-6

我们正在尝试设置卷影副本系统,以审核项目数据库中的某些表。对于任何更改(添加,更新,删除),该记录的副本将保存到其影子表中(我们使用的是术语版本)。

如果我们有一个名为Profiles的表,其中包含列(int)ProfileId,(varchar(50))Name,(date)UpdateDate等...我们将有另一个名为ProfilesVersion的表,其中包含列(int)ProfileVersionId,(int )ProfileId,(varchar(50))名称,(日期)UpdateDate等...

我正在制作系统来制作副本。在过去,我在数据库中使用了触发器来捕获插入,更新,删除。但现在我们正在尝试使用Entity Framework和Linq。

我可以覆盖DbContext上的SaveChanges,并在Version表中获得第二个副本。但是,在第一个表中填充的密钥ID不会在Version表中结束。

使用Entity Framework,您可以对数据库进行两次插入,并将来自一个实体的数据应用于第二个实体。例如:

var res = new Resource{
    SomeValue = someParameter
};
_db.Resource.Add(res);

var newProfile = new Profile{
    ProfileValue = anotherParameter, 
    ForeignResourceId = res.ResourceId // ResourceId is autogenerated
};

_db.Profile.Add(newProfile);
_db.SaveChanges();

var forResourceId = newProfile.ForeignResourceId; 

由于Profile.ForeignResourceId和Resource.ResourceId在模型中映射,因此newProfile对象具有在SaveChanges()之后由数据库分配的ForeignResourceId。不知何故,实体框架知道将res.ResourceId从数据库生成后放入ForeignResourceId。

我将代码从一个实体动态复制到Version表中的代码不会这样做。它只是将第一个实体的数据复制到Version实体的新记录中,但是没有设置关系以使用外键填充关键字段。

public int SaveChanges(Guid userId)
{
    // ... some other code

    // entityEntry is DbEntityEntry, the entity with changes we want to replicate

    // Create audit entity.
    DbSet set = this.Set(auditTypeInfo.AuditEntityType);
    IAuditEntity auditEntity = set.Create() as IAuditEntity;
    set.Add(auditEntity);

    // Copy the properties.
    DbEntityEntry auditEntityEntry = this.Entry(auditEntity);
    foreach (string propertyName in auditTypeInfo.AuditProperties)
    {
        // This copies just the raw value, if any
        auditEntityEntry.Property(propertyName).CurrentValue = entityEntry.Property(propertyName).CurrentValue; 
    }

    // ... 

    return base.SaveChanges();
}

因此,按照我们的示例,如果我们添加一个Profile记录,它就是它的ProfileId,但是ProfileVersion记录没有。

在上面的代码中,如何让实体框架在我们要复制的'auditentity'中设置该值?

1 个答案:

答案 0 :(得分:0)

如果我理解你的情况,那么:

这将与您的实体的属性有关。如果你的实体有属性(我想,它是你实体的关键)有DatabaseGeneratedOption.Identity(在OnModelCreating分配),在sql级别转换为IDENTITY (1,1),你什么都没有do,因为所有这些都是在数据库处理,而不是ORM级别。

在这种情况下您可以做什么,使用IDENTITY_INSERT,这将允许您分配ID,但是,这意味着您还必须手动生成ID。

简而言之 - 摆脱自动身份生成。