3

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

    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 方法中的审计字段。

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

问题: 是否有一些实体框架忍者技术,我可以拦截对多对多关系的更改并根据需要更新链接表审计字段,而不必在模型中明确包含“链接”实体?

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

谢谢你的时间!

4

2 回答 2

0

病人:“医生,我做这个的时候很痛,有什么药?” 医生:“不要那样做。”

我将回答我自己的问题,因为“没有答案”。正如我在有关 StackOverflow 问题的评论中看到的其他人所建议的那样——我认为在模型中明确包含“链接”实体最终会更好。

于 2013-06-13T16:37:12.773 回答
0

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

那么如何拦截变化呢?

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

编辑:

作为参考,这里是我发布的原始示例,它可能使您相信您必须将 sql 放入您的模型中

于 2013-06-07T08:58:08.693 回答