简体   繁体   English

在调用 SaveChanges() 之前添加实体的访问 id

[英]access id of added entity before SaveChanges() is called

i'm using EF 4.3.1, I've overridden the SaveChanges() on the context so that I can get a list of the objects and their states and create entries in my audit log table.我正在使用 EF 4.3.1,我已经覆盖了上下文中的 SaveChanges(),以便我可以获得对象及其状态的列表并在我的审计日志表中创建条目。 I need to store the id of the record in the audit log table so i have a reference to it.我需要将记录的 id 存储在审计日志表中,以便对其进行引用。 This is a problem when records are inserted, as I don't have access to the id before it's saved.这是插入记录时出现的问题,因为在保存之前我无法访问 id。 Is there any way of getting the id at that point?有什么方法可以在那时获得 id 吗?

public override int SaveChanges()
{
        ChangeTracker.DetectChanges();

        var objectStateManager = ((IObjectContextAdapter)this).ObjectContext.ObjectStateManager;
        var modifiedAuditableEntities = objectStateManager.GetObjectStateEntries(EntityState.Modified | EntityState.Added).Where(e => (IAuditable)e.Entity != null);

        foreach (var entry in modifiedAuditableEntities)
        {
            var entity = (IAuditable)entry.Entity;

            if (entity != null)
            {
                switch (entry.State)
                {
                    case EntityState.Added:
                        entity.IsAdded = true;
                        break;
                    case EntityState.Deleted:
                        entity.IsDeleted = true;
                        break;
                    case EntityState.Modified:
                        entity.IsModified = true;
                        break;
                }

                this.EntitySet<AuditLogEntry>().Add(this.auditLogService.CreateAuditLogEntryForEntity((IAuditable)entry.Entity));
            }
        return base.SaveChanges();
}

If your goal is that you want both your save, and your audit log to be created at the same time, you could wrap it in a transaction scope so your method to be atomic.如果您的目标是希望同时创建保存和审核日志,则可以将其包装在事务范围中,以便您的方法是原子的。

    public override int SaveChanges()
    {
        ChangeTracker.DetectChanges();
        using (var scope = new TransactionScope())
        {
            var objectStateManager = ((IObjectContextAdapter) this).ObjectContext.ObjectStateManager;
            var modifiedAuditableEntities =
                objectStateManager.GetObjectStateEntries(EntityState.Modified | EntityState.Added).Where(
                    e => (IAuditable) e.Entity != null);
            var result = base.SaveChanges();
            foreach (var entry in modifiedAuditableEntities)
            {
                var entity = (IAuditable) entry.Entity;

                if (entity != null)
                {
                    switch (entry.State)
                    {
                        case EntityState.Added:
                            entity.IsAdded = true;
                            break;
                        case EntityState.Deleted:
                            entity.IsDeleted = true;
                            break;
                        case EntityState.Modified:
                            entity.IsModified = true;
                            break;
                    }

                    this.EntitySet<AuditLogEntry>().Add(
                        this.auditLogService.CreateAuditLogEntryForEntity((IAuditable) entry.Entity));
                }
            }
            base.SaveChanges();

            scope.Complete();
            return result;
        }
    }

Id the Id is an integer generated by the database there isnt any way of getting it before calling save changes. Id Id 是数据库生成的整数,在调​​用保存更改之前没有任何方法可以获取它。 Possible solutions include:可能的解决方案包括:

  • Triggers触发器
  • Using Guids as Primary Keys使用 Guid 作为主键
  • Using a key generation strategy not managed by the database (HiLo in NHibernate)使用不受数据库管理的密钥生成策略(NHibernate 中的 HiLo)
  • Calling base.SaveChanges() first then inspecting the results.首先调用 base.SaveChanges() 然后检查结果。

I would recommend using a stored procedure at the database level to perform your insert/auditing functions (and other database changes), and revoking the insert/update/delete permission from your users.我建议在数据库级别使用存储过程来执行插入/审核功能(和其他数据库更改),并撤销用户的插入/更新/删除权限。 As such you can guarantee the integrity of the update process and of the audit table.因此,您可以保证更新过程和审计表的完整性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在SaveChanges方法之前将获得对新插入的Identity ID的访问权限 - Getting access to newly inserted Identity ID before SaveChanges method will be called 实体框架 - 在事务内的“SaveChanges”之前检索 ID - Entity Framework - retrieve ID before 'SaveChanges' inside a transaction 如何在SaveChanges之前搜索实体 - How to search for an entity before the SaveChanges 调用DataContext.SaveChanges()时,C#MVC实体框架,子ID,孙ID不必要地增加 - C# MVC Entity Framework, child ID, grandchild ID is unnecessarily incrementing when DataContext.SaveChanges() is called c#Entity Framework在SaveChanges之前从数据上下文中删除添加的对象 - c# Entity Framework Remove an added object from the Data Context before SaveChanges C# 如何在实体框架中的 SaveChanges 之前删除新添加的记录 - C# How Can I Remove New Added Record Before SaveChanges in Entity Framework 实体框架ObjectContext在SaveChanges之前删除实体 - Entity Framework ObjectContext Remove Entity Before SaveChanges 实体框架 - 在调用 SaveChanges() 以添加/删除实体之前从上下文获取更新的数据库集 - Entity Framework - Get Updated DB set from context before SaveChanges() is called to add/remove entities 在调用SaveChanges()之前,在Add()之后从上下文中检索实体 - Retrieving entity from context after Add() yet before SaveChanges() has been called 实体处理项已添加到数据库,但SaveChanges失败 - Entity handling items added to database but SaveChanges fails
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM