I have an EntityService
class which wraps around entity operations and also provides the WPF application ObservableCollection
s of materialized entities.
When I come to delete a Book from my collection of Books
:
<Class EntityService>
public void DeleteBook(Book book)
{
context.DeleteObject(book)
observableCollectionOfBooks.Remove(book)
}
EntityFramework
then proceeds to null all the navigation properties of the to-be-deleted Book which fires off PropertyChanged
events. One of my ViewModels is an observer of this event:
<Class LibraryViewModel>
private void BookPropertyChanged(object sender, PropertyChangedEventArgs e)
{
//Get all materialized books
var books = entityService.Books.Where(x => x.Author.Name == "Dan");
}
Here I get a NullReferenceException
because the deleted Book hasn't been removed from the ObservableCollection
yet and the Author
for the to-be-deleted Book
is null
.
I've tried changing the order of operations in DeleteBook(Book book)
but it produces a different but related inconsistency.
The problem is that the operation is not atomic.
What I'm looking for is BookPropertyChanged
to be called only when the model is in a consistent state: The Book
is in deleted and the ObservableCollection
doesn't contain the deleted object.
I realise there may be some hack to fix this such as checking for nulls but I was wondering if there was a better way?
I was thinking of somehow suppressing the events until both operations were completed. I'm not s开发者_如何学Cure how this would work even in theory but I think I need to achieve something equivalent to the following:
using (new EventSuppressor(book, observableCollectionOfBooks))
{
context.DeleteObject(book)
observableCollectionOfBooks.Remove(book)
}
So here, any objects passed into the EventSuppressor constructor will have their event notifications suppressed and cached up. The operations inside the using block can take place. When the suppressor is disposed, all events that would have been fired due to the operations executed in the using block are now fired.
I may be way off, but, what if you try the below?
public void DeleteBook(Book book)
{
context.DeleteObject(book);
context.SaveChanges();
observableCollectionOfBooks.Remove(book);
}
精彩评论