How to properly use Object Contexts in Entity Framework using BackgroundWorker - entity-framework

I am developing using Entity Framework and WPF, and I am encountering some errors and I don't know why. When saving a record (using a BackgroundWorker), I set the entities change tracker to nothing (null), attach the record to a new disposable context, save it, detach, and dispose of the context.
Saving a record fires and event in theMainViewModel of the program that the other ViewModels (including the one that is saving) need to refresh their entities to reflect changes.
Private Sub _saveRecordWorker_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles _saveRecordWorker.DoWork
Using MyContext As New RVShippingEntities
Dim MyShipment = CType(ShipmentRecord, IEntityWithChangeTracker)
MyShipment.SetChangeTracker(Nothing)
MyContext.Attach(MyShipment)
MyContext.Detach(ShipmentRecord)
End Using
End Sub
The Refresh background worker is similar, but it has a Do While block to keep it from interfering with the save worker (which doesn't appear to be working; hence the post). When I save (and it subsequently refreshes) I get the following error:
The calling thread cannot access this object because a different thread owns it.
I thought that with theDoWhile block, it would wait (and when I step through it does) until the save thread finished, and all would be good. But it would seem that something (either the main thread or the save thread) is still doing something that is interfering.
Is there a better way of doing this? Am I doing it in a goofy kludgey fashion? Any help would be appreciated.
(Apparently Firefox recognized kludgey as a word. Interesting)

So, 3+ months and nary an exception so far in relation to Entity Framework. I am going to call this the answer.
Parent Views (in my case Company, Customer, Shipment) have a context which is passed to child Views as necessary (Addresses, Phone Nums, Email Addresses, for Company and Customer; Packages, Contents, for Shipments). Anytime a context can't save changes or what have you (db disconnection is most common cause), the context is disposed, a new one instanced, the entities are re-attached, set to modified (based on custom change tracking which I do for UI), and changes are saved.

Related

Storing a complex detached object graph in EF6

I have the current scenario:
I'm using EF6 Code first, and have created a data-model something like this:
public class MainObject{
..some properties
IList<SubObject> SubObjects{get;set;}
}
public class SubObject{
..some properties
IList<SubSubObject> SubSubObjects{get;set;}
}
public class SubObject{
..some properties
IList<SubObject> SubObjects{get;set;}
}
So basically I have a main object, that has 0 to many subobjects, and there is a many to many relationship between the subobject and the subsubobjects.
I am creating a MVC application, so my normal program flow is that the user request a page that basically uses a MainObject as it's data model. Then the user interacts with the page and changes, adds or removes subobjects and subsubobjects as he wishes, and then clicks save. On save, the objectgraph is sent back to the controller and it looks correct according to the changes done by the user on the client side. Now my problem is the following:
How to store this back into the database in a good fashion.
I need to attach my object back into the context, but I have no clue which objects are new, modified or deleted.
I have written some code that partially works now, but it's getting so ugly that I really don't want to go down that path. Would it be possible somehow to fetch the relevant object graph from the database, and have EF compare the two graphs toward eachother, and then save the relevant changes to the database?
Any help to make this smoother would be greatly appreciated.
I ended up using GraphDiff to solve this for me, and it works just great! This really should be built into EF, but untill it does, this is a great substitute.
To solve the example given in my question above, this will make sure that the detached graph gets saved properly (given I have a MainObject I want to save called main):
context.UpdateGraph(main, map =>map
.AssociatedCollection( m => m.SubObjects, with => with
.AssociatedCollection( s => s.SubSubObjects)
)
);
context.SaveChanges();

How to fix "EntityMemberChanged was called without first calling EntityMemberChanging"

This came up time and again for us. After reading such a message, there's nothing intuitive to do and debug.
What this poorly-documented error is trying to say is that you accidentally set up a system in which tracking changes causes more changes.
When Entity Framework changed a property on one of your entities, such as during SaveChanges with identity ID updates, you ran code that changed other tracked properties.
For example, the property that Entity Framework was setting triggered an event, perhaps INotifyPropertyChanged, which perhaps was subscribed to by a BindingSource or some binding list, whose ListChanged event handler was in the UI and triggered a calculation of some other property, and the change tracker detected the second property change.
The simple diagnosis is to place a breakpoint on the SaveChanges() call and immediately after the SaveChanges call(). When the first breakpoint is hit, place a breakpoint on each event handler that could possibly be triggered. (BindingSources are notorious for multiplying each other's events.) Continue debugging. If any breakpoint is hit other than the point immediately following SaveChanges, you know where the problem is.
The simple solution is to set a flag, such as IsSaving, on each side of the SaveChanges call. Then in each misbehaving event handler, do a simple check and do not modify any entities if the DbContext is in the process of saving. Make sure you use finally in case SaveChanges throws an exception that you catch at a higher level:
IsSaving = true;
try
{
await db.SaveChangesAsync()
}
finally
{
IsSaving = false;
}
(One other possibility is that you were changing the entity from multiple threads — never involve the change tracker in multiple threads!)
I had the exact same issue. I had wired to the INotifyPropertyChanged event that created the possibility for a property to change during the SaveChanges() call. I think it is a better practice to unwire the event handlers of you tracked entities when performing dbContext.SaveChanges(), Remove().
I'll explain my experience with this error, hoping it might help someone. And thanks to jnm2 for beautiful explanation.
I had Invoice and Receipt entities, and InvoiceViewModel.
Thie ViewModel was subscribed to Invoice property changed, inside which it was raising CanExecuteChanged events.
I added Receipt to Invoice navigation property and called SaveChanges(), which raised Invoice.ReceiptID property changed and triggered OnPropertyChanged event handler on the ViewModel, which in turn raised all kinds of CanExecuteChanged events.
The problem was that one of the CanCommandNameExecute methods was calling Context.ChangeTracker.HasChanges() which ultimately threw an exception.
How I fixed it?
I followed jnm2, I flagged VM with IsSaving and checked for the flag inside OnPropertyChanged event handler.
Once again, thanks jnm2, and hope someone finds this helpful as well.

Entity Framework 5 Unit of Work pattern - where should I call SaveChanges?

Apologies, in advance, if this seems like a duplicate question. This question was the closest I could find, but it doesn't really solve the issues I am facing.
I'm using Entity Framework 5 in an ASP.NET MVC4 application and attempting to implement the Unit of Work pattern.
My unit of work class implements IDisposable and contains a single instance of my DbContext-derived object context class, as well as a number of repositories, each of which derives from a generic base repository class that exposes all the usual repository functionality.
For each HTTP request, Ninject creates a single instance of the Unit of Work class and injects it into the controllers, automatically disposing it when the request is complete.
Since EF5 abstracts away the data storage and Ninject manages the lifetime of the object context, it seems like the perfect way for consuming code to access in-memory entity objects without the need to explcitly manage their persistence. In other words, for optimum separation of concerns, I envisage my controller action methods being able to use and modify repository data without the need to explicitly call SaveChanges afterwards.
My first (naiive) attempt to implement this idea employed a call to SaveChanges within every repository base-class method that modified data. Of course, I soon realized that this is neither performance optimized (especially when making multiple successive calls to the same method), nor does it accommodate situations where an action method directly modifies a property of an object retrieved from a repository.
So, I evolved my design to eliminate these premature calls to SaveChanges and replace them with a single call when the Unit of Work instance is disposed. This seemed like the cleanest implementation of the Unit of Work pattern in MVC, since a unit of work is naturally scoped to a request.
Unfortunately, after building this concept, I discovered its fatal flaw - the fact that objects added to or deleted from a DbContext are not reflected, even locally, until SaveChanges has been called.
So, what are your thoughts on the idea that consuming code should be able to use objects without explicitly persisting them? And, if this idea seems valid, what's the best way to achieve it with EF5?
Many thanks for your suggestions,
Tim
UPDATE: Based on #Wahid's response, I am adding below some test code that shows some of the situations in which it becomes essential for the consuming code to explicitly call SaveChanges:
var unitOfWork = _kernel.Get<IUnitOfWork>();
var terms = unitOfWork.Terms.Entities;
// Purge the table so as to start with a known state
foreach (var term in terms)
{
terms.Remove(term);
}
unitOfWork.SaveChanges();
Assert.AreEqual(0, terms.Count());
// Verify that additions are not even reflected locally until committed.
var created = new Term { Pattern = "Test" };
terms.Add(created);
Assert.AreEqual(0, terms.Count());
// Verify that additions are reflected locally once committed.
unitOfWork.SaveChanges();
Assert.AreEqual(1, terms.Count());
// Verify that property modifications to entities are reflected locally immediately
created.Pattern = "Test2";
var another = terms.Single(term => term.Id == created.Id);
Assert.AreEqual("Test2", another.Pattern);
Assert.True(ReferenceEquals(created, another));
// Verify that queries against property changes fail until committed
Assert.IsNull(terms.FirstOrDefault(term => term.Pattern == "Test2"));
// Verify that queries against property changes work once committed
unitOfWork.SaveChanges();
Assert.NotNull(terms.FirstOrDefault(term => term.Pattern == "Test2"));
// Verify that deletions are not even reflected locally until committed.
terms.Remove(created);
Assert.AreEqual(1, terms.Count());
// Verify that additions are reflected locally once committed.
unitOfWork.SaveChanges();
Assert.AreEqual(0, terms.Count());
First of all SaveChanges should NOT be ever in the repositories at all. Because that's leads you to lose the benefit of UnitOfWork.
Second you need to make a special method to save changes in the UnitOfWork.
And if you want to call this method automatically then you may fine some other solution like ActionFilter or maybe by making all your Controllers inherits from BaseController class and handle the SaveChanges in it.
Anyway the UnitOfWork should always have SaveChanges method.

GWT MVP updating Activity state on Place change

What is the best practise to update Activity state on Place change? Imagine you have an activity with view that displays list of categories and list of items in the category. If different category is selected then app goes to new place with category ID. I want then to only refresh items and not to create new activity that also re-reads category list.
My current approach is like this:
public class AppActivityMapper implements ActivityMapper {
private ItemListActivity itemListActivity;
...
public Activity getActivity(final Place place) {
final Activity activity;
if (place instanceof ItemListPlace) {
if (itemListActivity == null) {
itemListActivity = new ItemListActivity((ItemListPlace) place, clientFactory);
} else {
itemListActivity.refresh((ItemListPlace) place);
}
activity = itemListActivity;
} else {
itemListActivity = null;
}
...
return activity;
}
...
Alternatives are:
listen to PlaceChangeEvents from within the activity (you can then use a FilteredActivityMapper and CachingActivityMapper for the caching of the activity in your ActivityMapper, so that it's reduced to only create a new activity when asked). †
have some component listen to PlaceChangeEvents and translate them to business-oriented events, the activity then listens to those events rather than PlaceChangeEvents, otherwise the same as above.
decouple the activity from the "screen", make the "screen" a singleton with a reset() method and call that method from the activity's start (possibly passing the category ID as an argument in this case). The "screen" being a singleton could then make sure to load the categories list only once.
in your case, you could also simply put the categories list in a shared cache, so that you don't have to reuse your activity by can create a new one, the categories list will be retrieved once and put in the cache, subsequent activity instances will just use what's in the cache. This is similar to the above, but simpler, and the cache could be used by other parts of the application.
I'd personally rather go with your approach though (with a small exception, see below), as it's the simplest/easiest. Decoupling the activity from the "screen" is also an option; the GWT Team started exploring this approach in the Expenses sample (decoupling the activity responsibility from the presenter responsibility with using MVP) without ever finishing it unfortunately.
Other than that, I don't think any best practice has really emerged for now.
†. I don't like coupling my activities with the places they're used with (I don't quite like the coupling for the goTo calls either, but haven't yet found a clean and simple alternative), so I'd rather not go with this option; and similarly, I'd not pass the place to the activity constructor and refresh method like you did, but rather extract the information out of the place and pass it to the activity (e.g. in your case, only give the category ID to the activity, not the ItemListPlace instance; I would then simply call setCategory in all cases, and not even pass the category ID to the constructor).
In my opinion,
The role of the ActivityMapper is to give you back an Activity from a Place.
The role of the ActivityManager is to start the Activity given back from the ActivityMapper and to stop the current one if different. In your case you would like to "update/refresh" the current Activity.
So I would modify the ActivityMapper so as it will allways give me back the same instance of Activity for a given type of Place. A good way to do so could be to use GIN and use the singleton scope ...in(Singleton.class) to inject your Activity.
If you do that, when changing the url, if the place stays the same (meaning your url has the same word after # and before :) so that the Type of your place stays the same, the ActivityMapper will give you back the same instance of Activity so the ActivityManager will do nothing on the Activity. Check l.126 of ActivityManager
if (currentActivity.equals(nextActivity)) {
return;
}
For me you have 2 options there. The first one, as Thomas said , is to listen to PlaceChangeEvent in your Activity. The new Place you will receive can have new parameters inside based on the new url given and you can "update/refresh" your Activity.
The second one, that I find more in line with the Activity/Place pattern is to modify the ActivityManager so that it calls an update(Place) method on the Activity when the Activity given back by the ActivityMapper is the same that the current Activity.
I haven't tried any of these solutions yet but I will soon ... I might be able to update that post at that time.
You can find more information in this article I wrote on my blog on that topic
Here is a little schema I made to help me understand the pattern, hope it will help :
I would not do any logic in my ActiviyMapper except returning an activity, by creating a new one or giving a previous one (or null). According to me, the mapper doesn't have to know about refresh() or what activities do.
If that, then the logic of 'refresh()' would be given to the activy through the place which holds a token. That token should be holding the information about either what is the state of the request (a new page, reload, an id, etc).
In the activity, first, it asks for the View, the one related to this activity (tip : a singleton given by a 'ClientFactory' is good practice), then it creates a presenter for that view, and bind them together.
Lastly, the activity will use the token from the place to provide any information about state to the presenter. And then, it adds the view in the page.
It's good to know by default, with places and activies, going to the same place doesn't do anything (no reload). But you can take care of it with token and activity-mapper easily.
Hope you'll find an adapted solution for you case. Goodluck.

GWT: Is it OK to edit the same proxy multiple times?

I'm using GWT 2.4 with RequestFactory but not still everything is clear for me.
In this article author wrote about situation when we used an entity proxy with one instance of RequestContext and want to reuse (edit()) this entity proxy with other instance of RequestContext:
It cannot be edited because it has already a requestContext assigned.
If you want to change it you must retrieve instance of this entity
from server again
But I'm getting no exceptions when I execute this code:
RequestContext newRequest1 = factory.myRequest();
newRequest1.edit(proxy);
RequestContext newRequest2 = factory.myRequest();
newRequest2.edit(proxy);
The problems (exception) described by autor pop up when I run this version:
RequestContext newRequest1 = factory.myRequest();
MyProxy edited = newRequest1.edit(proxy);
RequestContext newRequest2 = factory.myRequest();
newRequest2.edit(edited);
So it seems that only editable copy returned by edit() is directly related with RequestContext instance.
In that case is there something wrong in approoach in which I keep one instance of (uneditable/frozen) proxy in my edit view and each time user clicks "edit" button I edit() it with new fresh RequestContext? Or should I obtain fresh instance of proxy each time too?
Getting new instance of proxy seems a bit awkward for me but I guess reusing one proxy instance may cause some issues related to sending delta of changes to server?
So to rephrase the question: it a good practice to reuse single instance of proxy with multiple RequestContexts?
There's no problem editing the same proxy twice (or more), as long as there's only a single editable instance at a time (your first code snippet should throw; if it's not then it's a bug; it could work if you don't keep references on both the RequestContext and the edited proxy).
Note that RequestFactory sends only the modified properties to the server, but it does so by diff'ing with the non-editable instance passed to edit(); so you should try to use the most recent instance as possible to keep your server-side/persisted data as close to your client-side data as possible (could seem obvious, but can lead to some surprises in practice: if you see foo on the client but have bar on the server, you'll keep the bar on the server-side until you modify the property on the client-side to something other than foo)