Я смотрю на службы данных WCF, особенно на реализацию отслеживания изменений в DataServiceCollection
.
Давайте рассмотрим сценарий отмены в приложении, которое управляет блогами и записями в блогах (в каждом блоге много записей в блогах). Я тестирую два вида операций отмены:
- добавлена новая запись в блоге (операция отмены — удаление записи);
- существующая запись в блоге была удалена (операция отмены заключается в добавлении записи).
Вот пример кода:
var context = new BloggingContext(new Uri("http://localhost/WCFDataServicesDemo/"));
var blogs = new DataServiceCollection<Blog>(context.Blogs.Expand(b => b.Entries), TrackingMode.AutoChangeTracking);
var blog = blogs.Where(b => b.Id == 1).Single();
// new entry
var newEntry = new BlogEntry
{
// some blog entry's properties
};
// add new entry
blog.Entries.Add(newEntry);
// undo add
blog.Entries.Remove(newEntry);
// existing entry
var existingEntry = blog.Entries[0];
// remove existing entry
blog.Entries.Remove(existingEntry);
// undo remove
blog.Entries.Add(existingEntry);
context.SaveChanges();
Первая операция отмены (добавить новую запись, а затем удалить ее при отмене) работает нормально.
Вторая операция отмены (удалить существующую запись, а затем добавить ее при отмене) работает асимметрично.
Эта строка:
blog.Entries.Remove(existingEntry);
помечает соответствующий объект как Deleted
в средстве отслеживания изменений контекста, что правильно. Но эта строка:
blog.Entries.Add(existingEntry);
ничего не делает с трекером изменений (existingEntry
остается в состоянии Deleted
), но, конечно, добавляет элемент в коллекцию.
Следовательно, когда вызывается SaveChanges
, эта запись удаляется из базы данных, но остается в коллекции на стороне клиента.
Я пытался обрабатывать эту отмену вручную, устанавливая обратные вызовы в конструкторе DataServiceCollection
, но здесь я получаю такое же асимметричное поведение - collectionChangedCallback
не срабатывает, когда я пытаюсь добавить элемент, помеченный как Deleted
.
Что я делаю не так?
Как "восстановить" удаленный элемент?