更新多对多实体框架模型中的审核字段

时间:2013-06-04 19:00:11

标签: entity-framework entity-framework-5

我有一个具有多对多关系的遗留数据库,如下所示:

    public class Post  
    {
        public ICollection<Tag> Tags { get; set; }

        ...
    }

    public class Tag 
    {
        public ICollection<Post> Posts { get; set; }

        ...
    }

在'PostTagLink'表中跟踪多对多关系。

通常,使用Code First很容易或多或少地隐式表达多对多关系,即在添加或删除关系时更新“PostTagLink”表,但实际上没有明确地具有“PostTagLink”实体定义

保存更改时,DbContext可以轻松更新标签和帖子上的审核字段:

    public abstract class MyAuditableEntityContext : DbContext
    {
        public override int SaveChanges()
        {
            string currentUser = Thread.CurrentPrincipal.Identity.Name;

            foreach (DbEntityEntry<IAuditableEntity> changeEntry in base.ChangeTracker.Entries<IAuditableEntity>())
            {
                if (changeEntry.State == EntityState.Added)
                {
                    changeEntry.Entity.CreatedBy = currentUser;
                    changeEntry.Entity.RevisedBy = currentUser;
                }
                else if (changeEntry.State == EntityState.Modified)
                {
                    changeEntry.Entity.RevisedBy = currentUser;
                }
            }

            return base.SaveChanges();
        }
    }

但是如果'PostTagLink'表还包含审计字段怎么办?

我可以看到唯一的解决方案是在模型中包含一个PostTagLink实体(将多对一关系返回到Tag和Post),这样我就可以访问DbContext SaveChanges方法中的审计字段。

但是添加这些额外的实体会使模型的处理变得尴尬。客户端和查询必须直接处理“链接”实体,而不是自动处理关系更改的实体框架。

问题:是否存在一些Entity-Framework-ninja技术,我可以拦截多对多关系的更改并根据需要更新链接表审核字段,而无需明确包含模型中的“链接”实体?

(同样 - 这是一个遗留数据库,我无法改变它,所以我想避免向数据库添加存储过程或任何其他逻辑。)

谢谢你的时间!

2 个答案:

答案 0 :(得分:0)

因此,如果我理解正确,当您将项目添加到其中一个集合并保存实体时,您需要在多对多表中设置CreatedBy字段。您可以使用DbContext.Database.SqlCommand执行原始sql来更新链接表审计字段。 How to execute raw sql

那么如何拦截这些变化?

这些答案可能有所帮助:EF4 Audit changes of many to many relationshipsEntity Framework: Tracking changes to FK associations

修改

此处参考的是我发布的original example,可能让您相信您必须将sql放入模型中

答案 1 :(得分:0)

病人:“医生,我这样做会很疼。治愈的是什么?” 医生:“不要这样做。”

我将回答我自己的问题,因为“没有答案”。正如我已经看到其他人在相关StackOverflow问题的评论中提出建议 - 我认为最好只在模型中明确包含'链接'实体。