Перевірте, чи є якісь зміни, що очікують на збереження


75

Чи є спосіб дізнатись, чи є незбережені зміни в моєму контексті сутності, в Entity Framework?


Чи не перевіряє context.savechanges () це автоматично? Причина, по якій я запитую, полягає в тому, що я думаю, що кілька людей спробують зробити наступне: if (db.ChangeTracker.HasChanges()) { await db.SaveChangesAsync(); }
— Zapnologica

Відповіді:


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
+1 за те, що, як правило, на правильному шляху, але використовуйте Any()ні Count() > 0.
— Крейг Стунтц,

Прокляття - просто прочитайте сьогодні свій блог щодо цього! Спасибі;)
— Якімич

Зауважте, що EF не перевіряє, чи значення насправді відрізняється (для EntityState.Modified). eq, якщо замінити значення самостійно, EF повернеться 1 modified object. Вам слід заздалегідь перевірити, чи не відрізняється значення.
— Матьє Шарбоньє

102

Починаючи з EF 6, є context.ChangeTracker.HasChanges().


3
Найсвіжіша відповідь.
— Zapnologica

1
Станом на 2016 рік, це відповідь, ІМХО.
— ozgur

Зараз це найкраща відповідь, як згадали інші.
— Йокомоко

Акуратне рішення! Дякую, що поділились. Чи знаєте ви, як вчасно вловити зміни та позначити змінену форму "*"? наприклад: Form1 *
— Рапунцо,

43

Для тих, хто використовує 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).
— Крістіан

1
EntityStateбо EntityState.Addedє від, System.Data.Entityа не від System.Data.
— Юк
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.