检查是否有待保存的更改。

81

有没有一种方法可以在Entity Framework中找出我实体上下文中是否存在未保存的更改?


2
context.savechanges()不会自动检查吗?我问这个问题的原因是我认为有些人会尝试做以下操作:if (db.ChangeTracker.HasChanges()) { await db.SaveChangesAsync(); } - Zapnologica
3个回答

124

从 EF 6 开始,有 context.ChangeTracker.HasChanges() 方法。


3
最新答案。 - Zapnologica
1
截至2016年,这是我的看法。 - ozgur
这是现在最佳答案,正如其他人所提到的。 - Yokomoko
好的解决方案!感谢分享。您知道如何及时捕获更改并在修改后用“”标记修改的表单吗? 例如:Form1 - Rapunzo

61

这可能有效(如果更改意味着添加、删除和修改实体):

bool changesMade = (context.ObjectStateManager.GetObjectStateEntries(EntityState.Added).Count() +
                    context.ObjectStateManager.GetObjectStateEntries(EntityState.Deleted).Count() +
                    context.ObjectStateManager.GetObjectStateEntries(EntityState.Modified).Count()
                    ) > 0;

编辑:

改进的代码:

bool changesMade = context.
                   ObjectStateManager.
                   GetObjectStateEntries(EntityState.Added | 
                                         EntityState.Deleted | 
                                         EntityState.Modified
                                        ).Any();

12
一般来说你的方向是正确的,但应该使用Any()而不是Count() > 0 - Craig Stuntz
真糟糕 - 今天刚看了你的博客文章!谢谢 ;) - Yakimych
请注意,EF不会检查值是否真的不同(对于“EntityState.Modified”)。例如,如果您将一个值替换为它本身,EF将返回“1个修改对象”。您必须事先检查该值是否不同。 - Matthieu Charbonnier

46

如果你正在使用 EF 4+,这里有一个等效的解决方案,它是作为扩展方法实现的:

public static class DbContextExtensions {
    public static Boolean HasPendingChanges(this DbContext context) {
        return context.ChangeTracker.Entries()
                      .Any(e => e.State == EntityState.Added
                             || e.State == EntityState.Deleted
                             || e.State == EntityState.Modified);
    }
}

请注意,您无法将值组合为位掩码。函数GetObjectStateEntries()已为您处理了逻辑,但LINQ不会产生正确的结果。


4
谢谢,被采纳的答案对我没有用,而你的答案(针对EF v.4.3)却起效了。 - Christian
1
EntityState.Added 是来自于 System.Data.Entity 而不是 System.Data - Yuck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接