使用EF映射“仅插入”表

时间:2013-01-18 00:11:29

标签: c# entity-framework entity-framework-5

我想保存对Comment实体/表格所做的所有更改的历史记录。

我的方法:
- 使用"insert only" table
- 使用composite PK,由db生成的int键和db生成的DateTime戳记组成 - 在实体上使用AsNoTracking

但是,假设它是该实体的导航属性:

public Article { 
  public int ID { get; set; }
  public string Title { get; set; }
  public string Content { get; set; }
  public virtual Comment Comments { get; set; }
}

因此,如果我致电articleFoo.Comments,它将获得所有实体,这意味着所有修订。我只想得到“最新的”。我怎么做到这一点?

--- --- UPDATE

  1. 如果我使用Linq过滤,那么我将如何处理它,或者 如果我使用sprocs选项那么我该怎么做?
  2. 我的假设是不完整的 - 我必须生成复合密钥,因为对于两个修订实体,它们的ID必须相等,但它们的更新日期时间必须不同。所以我不能让db自动生成那些,或者我可以吗?

1 个答案:

答案 0 :(得分:0)

您可以通过为Comments创建影子或审核表来转到仅限Db的路径。这将使用表触发器跟踪字段级别的所有插入,修改和删除。我环顾四周找了一个工具,让它变得更容易,我在CodeProject here上找到了一个 - 但如果你再搜索一下,你会发现更好的东西。

如果这不能漂浮你的船那么......

通过EF,您可以在提交之前检查新的,更新的或删除的评论记录,并在提交之前添加历史信息。

例如,使用ObjectContext.SavingChanges检查并记录更改,然后将自己的历史记录添加到上下文中。

在我的示例中,我的DbContext实例是StackOverflowEntities我在其中添加了基础ObjectContext.SaveChanges事件的事件处理程序

    // SavingChanges event handler. 
    private void context_SavingChanges(object sender, EventArgs e) {

        ObjectContext objectContext = sender as ObjectContext;

        if (objectContext != null) {
            foreach (ObjectStateEntry entry in objectContext.ObjectStateManager
                            .GetObjectStateEntries(EntityState.Added | EntityState.Modified | EntityState.Deleted)
                            .Where(et => et.Entity.GetType().Equals(typeof(Comment)))) {

                Comment comment = entry.Entity as Comment;
                Comment_Audit audit = new Comment_Audit {
                    BodyText = comment.BodyText,
                    Commentor = comment.Commentor,
                    ..
                    ..
                    ChangedAt = DateTime.Now,
                    ChangeType = entry.State.ToString()

                };

                StackOverflowEntities.Set<Comment_Audit>().Add(audit);

            }
        }
    }

现在,每次更改Comment时,都会添加一条审核记录,并随之保存。