I know this question has been asked and discussed a lot (e.g. Here and Here and this Article). Nevertheless, i still feel confused about it. I know that DbContext
s should not live for the duration of application lifetime, i know they should be used per Form (window) or per Presenter. The problem is that i don't have Forms or Presenters. I have a single Form (Window) with many view models, some of them which live for the duration of the application and almost all of my view models depend on DbContext
(LOB application, WPF, MVVM, Sql Server CE).
My solution is to hide DbContext
behind a factory which is injected in all view models that need access to DbContext
and those view models create/dispose of the DbContext
when their corresponding view is loaded/unloaded.
I would like to know if this solution has any problems or if there is a better solution you could advise ?
Asked
Active
Viewed 3,108 times
0

Community
- 1
- 1

Ibrahim Najjar
- 19,178
- 4
- 69
- 95
1 Answers
0
I tend to lay my projects out as follows;
1) Presentation Layer:
Contains my Views and ViewModels
2) Business Layer:
Contains my business logic
3) Data Layer:
Contains my models
My Presentation layer calls into the business layer to populate local copies (held in the ViewModel) of the data I wish to use in my ViewModel / View.
This is achieved with a Using statement, something like;
Using DBContext As Entities = ConnectToDatabase()
Dim clsApprovalTypes As New Repositories.clsApprovalTypesRepository(DBContext)
dbResults = clsApprovalTypes.GetRecords()
End Using
Return dbResults
Here I simply pass in the Context into Repository, once the data has been returned, the "End Using" will dispose of my context.
To update the context with changes made in my ViewModel / View, I use an AddEdit routine, which accepts a record, and updates / Adds to the context as necessary, using a similar methodology to the above, something like;
Using DBContext As CriticalPathEntities = ConnectToDatabase()
Dim clsApprovalTypes As New Repositories.clsApprovalTypesRepository(DBContext)
clsApprovalTypes.AddEditRecord(ApprovalTypeToSave)
Try
clsApprovalTypes.SaveData()
Catch ex As Exception
Return ex
End Try
End Using
Where my AddEdit routine is something like;
SavedRecord = New ApprovalType 'Store the Saved Record for use later
Dim query = From c In DBContext.ApprovalTypes
Where c.ApprovalType_ID = RecordToSave.ApprovalType_ID
Select c
If query.Count > 0 Then
SavedRecord = query.FirstOrDefault
End If
'
' Use Reflection here to copy all matching Properties between the Source Entity
' and the Entity to be Saved...
'
SavedRecord = Classes.clsHelpers.CopyProperties(RecordToSave, SavedRecord)
If query.Count = 0 Then
Try
DBContext.ApprovalTypes.Add(SavedRecord)
Catch ex As EntityException
Return ex
End Try
End If
I wrote a little more about some of this here;

Community
- 1
- 1

PGallagher
- 3,123
- 2
- 26
- 37
-
Thanks for detailed explanation, from what i see in your method, you're using the context per method and disposing it when the method is finished, but i think this goes against what the article i linked too advices and calls this a micro usage of the context instead of letting the context live per method, let it live per presenter. – Ibrahim Najjar May 25 '13 at 00:15
-
1Yeah, I based my answer on the recommendation by Microsoft given here... http://msdn.microsoft.com/en-gb/library/cc853327.aspx, which recommends that the Context be enclosed in a `Using` statement. – PGallagher May 25 '13 at 08:30
-
1Your recommendation is correct and i would use a "using" statement in MVC applications inside a controller action method or inside a WCF service method.Plus, the link you shared says that if there is a binding and the context needs to live for the duration of the binding then you should dispose it manually. So i guess this is my situation, so i will consider this as the answer unless someone else comes up with another idea. – Ibrahim Najjar May 25 '13 at 11:03