实体框架 4 上下文?
我只是在寻找其他人在使用 EF4 时如何管理其上下文的反馈。我正在创建一个 MVC 应用程序,使用(我认为:))工作单元、服务层、存储库、EF4 w/POCO 技术。
我的控制器使用采用 UOW 的服务,然后利用存储库从 EF 获取 POCO。
这是否正确实施?
请看下面,如有任何反馈,我们将不胜感激!
控制器
Public Class MyController
Function ListCustomers() As ActionResult
Dim _UOW = New UnitOfWork
Dim _Service = New CustomerService(_UOW)
Dim _Model = New CustomersViewModel
_Model.Customers = _Service.GetCustomers
_UOW.Dispose()
Return View(_Model)
End Function
End Class
工作单元
Public Interface IUnitOfWork
Property Context As GTGContext
Sub Committ()
End Interface
Public Class UnitOfWork
Implements IDisposable, IUnitOfWork
Public Property Context As Domain.GTGContext Implements IUnitOfWork.Context
Public Sub New()
_Context = New GTGContext
End Sub
Public Sub Committ() Implements IUnitOfWork.Committ
_Context.SaveChanges()
End Sub
#Region "IDisposable Support"
Private _IsDisposed As Boolean
Protected Overridable Sub Dispose(ByVal Disposing As Boolean)
If (Not _IsDisposed) Then
If (Disposing) Then
If (_Context IsNot Nothing) Then
_Context.Dispose()
End If
End If
'TODO: Free unmanaged resources (unmanaged objects) and override Finalize() below.
End If
_IsDisposed = True
End Sub
'TODO: Override Finalize() only if Dispose(ByVal disposing As Boolean) above has code to free unmanaged resources.
'Protected Overrides Sub Finalize()
' Dispose(False)
' MyBase.Finalize()
'End Sub
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
End Class
服务
Public Class CustomerService
Private _UOW As IUnitOfWork
Private _Repo As Repository(Of Customer)
Public Sub New(UOW As IUnitOfWork)
_UOW = UOW
_Repo = New Repository(Of Customer)(_UOW)
End Sub
Public Function GetCustoemrs() As IQueryable(Of Customer)
' Any Business Logic Here
Return _Repo.GetCustomers()
End Function
End Class
存储库
Imports System.Data.Objects
Namespace Repositories
Public Interface IRepository(Of T As Class)
ReadOnly Property ObjectSet As IObjectSet(Of T)
ReadOnly Property UnitOfWork As IUnitOfWork
Function Query(ByVal Expression As Expressions.Expression(Of Func(Of T, Boolean))) As IQueryable(Of T)
Function GetFirst(ByVal Expression As Expressions.Expression(Of Func(Of T, Boolean))) As T
Function GetSingle(ByVal Expression As Expressions.Expression(Of Func(Of T, Boolean))) As T
Sub Add(ByVal Entity As T)
Sub Attach(ByVal Entity As T)
Sub Delete(ByVal Entity As T)
Sub SaveChanges()
End Interface
Public Class Repository(Of T As Class)
Implements IRepository(Of T)
#Region "Private Members/Properties"
Private _ObjectSet As IObjectSet(Of T)
Private ReadOnly Property ObjectSet As System.Data.Objects.IObjectSet(Of T) Implements IRepository(Of T).ObjectSet
Get
If (_ObjectSet Is Nothing) Then
_ObjectSet = UnitOfWork.Context.CreateObjectSet(Of T)()
End If
Return _ObjectSet
End Get
End Property
Private _UnitOfWork As IUnitOfWork
Private ReadOnly Property UnitOfWork As IUnitOfWork Implements IRepository(Of T).UnitOfWork
Get
Return _UnitOfWork
End Get
End Property
#End Region
#Region "Constructor(s)"
Public Sub New(ByVal UnitOfWork As IUnitOfWork)
If (UnitOfWork Is Nothing) Then
Throw New ArgumentNullException("UnitOfWork")
End If
_UnitOfWork = UnitOfWork
End Sub
#End Region
#Region "IRepository(Of T)"
Public Sub Add(ByVal Entity As T) Implements IRepository(Of T).Add
ObjectSet.AddObject(Entity)
End Sub
Public Sub Attach(ByVal Entity As T) Implements IRepository(Of T).Attach
ObjectSet.Attach(Entity)
UnitOfWork.Context.ObjectStateManager.ChangeObjectState(Entity, EntityState.Modified)
End Sub
Public Sub Delete(ByVal Entity As T) Implements IRepository(Of T).Delete
ObjectSet.DeleteObject(Entity)
End Sub
Public Function GetFirst(ByVal Expression As System.Linq.Expressions.Expression(Of System.Func(Of T, Boolean))) As T Implements IRepository(Of T).GetFirst
Return ObjectSet.FirstOrDefault(Expression)
End Function
Public Function GetSingle(ByVal Expression As System.Linq.Expressions.Expression(Of System.Func(Of T, Boolean))) As T Implements IRepository(Of T).GetSingle
Return ObjectSet.SingleOrDefault(Expression)
End Function
Public Function Query(ByVal Expression As System.Linq.Expressions.Expression(Of System.Func(Of T, Boolean))) As System.Linq.IQueryable(Of T) Implements IRepository(Of T).Query
Return ObjectSet.Where(Expression)
End Function
Public Sub SaveChanges() Implements IRepository(Of T).SaveChanges
UnitOfWork.Committ()
End Sub
#End Region
End Class
End Namespace
I was just looking for some feedback on what others are doing to manage their context when using EF4. I am creating an MVC app, using (I think :)) the Unit of Work, Service Layer, Repository, EF4 w/POCO technique.
My Controllers utilize services which take a UOW, which then utilize repositories to get POCO's from the EF.
Is this implemented correctly?
Have a look below, and any feedback is appreciated!!
Controller
Public Class MyController
Function ListCustomers() As ActionResult
Dim _UOW = New UnitOfWork
Dim _Service = New CustomerService(_UOW)
Dim _Model = New CustomersViewModel
_Model.Customers = _Service.GetCustomers
_UOW.Dispose()
Return View(_Model)
End Function
End Class
Unit of Work
Public Interface IUnitOfWork
Property Context As GTGContext
Sub Committ()
End Interface
Public Class UnitOfWork
Implements IDisposable, IUnitOfWork
Public Property Context As Domain.GTGContext Implements IUnitOfWork.Context
Public Sub New()
_Context = New GTGContext
End Sub
Public Sub Committ() Implements IUnitOfWork.Committ
_Context.SaveChanges()
End Sub
#Region "IDisposable Support"
Private _IsDisposed As Boolean
Protected Overridable Sub Dispose(ByVal Disposing As Boolean)
If (Not _IsDisposed) Then
If (Disposing) Then
If (_Context IsNot Nothing) Then
_Context.Dispose()
End If
End If
'TODO: Free unmanaged resources (unmanaged objects) and override Finalize() below.
End If
_IsDisposed = True
End Sub
'TODO: Override Finalize() only if Dispose(ByVal disposing As Boolean) above has code to free unmanaged resources.
'Protected Overrides Sub Finalize()
' Dispose(False)
' MyBase.Finalize()
'End Sub
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
End Class
Service
Public Class CustomerService
Private _UOW As IUnitOfWork
Private _Repo As Repository(Of Customer)
Public Sub New(UOW As IUnitOfWork)
_UOW = UOW
_Repo = New Repository(Of Customer)(_UOW)
End Sub
Public Function GetCustoemrs() As IQueryable(Of Customer)
' Any Business Logic Here
Return _Repo.GetCustomers()
End Function
End Class
Repository
Imports System.Data.Objects
Namespace Repositories
Public Interface IRepository(Of T As Class)
ReadOnly Property ObjectSet As IObjectSet(Of T)
ReadOnly Property UnitOfWork As IUnitOfWork
Function Query(ByVal Expression As Expressions.Expression(Of Func(Of T, Boolean))) As IQueryable(Of T)
Function GetFirst(ByVal Expression As Expressions.Expression(Of Func(Of T, Boolean))) As T
Function GetSingle(ByVal Expression As Expressions.Expression(Of Func(Of T, Boolean))) As T
Sub Add(ByVal Entity As T)
Sub Attach(ByVal Entity As T)
Sub Delete(ByVal Entity As T)
Sub SaveChanges()
End Interface
Public Class Repository(Of T As Class)
Implements IRepository(Of T)
#Region "Private Members/Properties"
Private _ObjectSet As IObjectSet(Of T)
Private ReadOnly Property ObjectSet As System.Data.Objects.IObjectSet(Of T) Implements IRepository(Of T).ObjectSet
Get
If (_ObjectSet Is Nothing) Then
_ObjectSet = UnitOfWork.Context.CreateObjectSet(Of T)()
End If
Return _ObjectSet
End Get
End Property
Private _UnitOfWork As IUnitOfWork
Private ReadOnly Property UnitOfWork As IUnitOfWork Implements IRepository(Of T).UnitOfWork
Get
Return _UnitOfWork
End Get
End Property
#End Region
#Region "Constructor(s)"
Public Sub New(ByVal UnitOfWork As IUnitOfWork)
If (UnitOfWork Is Nothing) Then
Throw New ArgumentNullException("UnitOfWork")
End If
_UnitOfWork = UnitOfWork
End Sub
#End Region
#Region "IRepository(Of T)"
Public Sub Add(ByVal Entity As T) Implements IRepository(Of T).Add
ObjectSet.AddObject(Entity)
End Sub
Public Sub Attach(ByVal Entity As T) Implements IRepository(Of T).Attach
ObjectSet.Attach(Entity)
UnitOfWork.Context.ObjectStateManager.ChangeObjectState(Entity, EntityState.Modified)
End Sub
Public Sub Delete(ByVal Entity As T) Implements IRepository(Of T).Delete
ObjectSet.DeleteObject(Entity)
End Sub
Public Function GetFirst(ByVal Expression As System.Linq.Expressions.Expression(Of System.Func(Of T, Boolean))) As T Implements IRepository(Of T).GetFirst
Return ObjectSet.FirstOrDefault(Expression)
End Function
Public Function GetSingle(ByVal Expression As System.Linq.Expressions.Expression(Of System.Func(Of T, Boolean))) As T Implements IRepository(Of T).GetSingle
Return ObjectSet.SingleOrDefault(Expression)
End Function
Public Function Query(ByVal Expression As System.Linq.Expressions.Expression(Of System.Func(Of T, Boolean))) As System.Linq.IQueryable(Of T) Implements IRepository(Of T).Query
Return ObjectSet.Where(Expression)
End Function
Public Sub SaveChanges() Implements IRepository(Of T).SaveChanges
UnitOfWork.Committ()
End Sub
#End Region
End Class
End Namespace
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
让我告诉你,我很长一段时间都在苦恼该采取什么方法,主要是在 StackOverflow 上:)
我决定实现这篇关于管理对象上下文的好文章(请注意允许多个上下文的修订版本)。
http://dotnetslackers.com/articles/ado_net/Managing-Entity-Framework-ObjectContext-lifespan-and-scope-in-n-layered-ASP-NET-applications.aspx
然后我实现了如下外观:
当然,它很旧,但是天哪,天哪,它很管用!
看,所有服务层/工作单元/存储库内容的问题是您最终不得不编写大量代码来支持它(当然 EF4 应该减少代码膨胀!)。每次添加新实体时,你猜怎么着?甚至更加繁琐的代码膨胀。
通过上面的方法,我将所有外观/工作单元支持代码填充到可重用的类库中,我所要做的就是编写我的外观代码,该代码只涉及实际执行某些操作的代码 - 并且它适用于多个上下文。
对我有用...哦,不要因为我使用“外观”这个词而责备我。我从来没有真正上过学;)
谢谢,
理查德·
P.S.周末愉快!
Let me tell you, I agonised over what approach to take for a long time, mostly on StackOverflow :)
I settled on an implementation of this fine article on managing the object context (take note of the ammended version allowing for multiple contexts).
http://dotnetslackers.com/articles/ado_net/Managing-Entity-Framework-ObjectContext-lifespan-and-scope-in-n-layered-ASP-NET-applications.aspx
Then I implemented facades like:
Sure, it's old but boy oh boy, it works!
See, the thing with all that service layer / unit of work / repository stuff is you end up having to write a hell of a lot of code just to support it (and surely EF4 was supposed to reduce code bloat!). Every time you add a new entity, guess what? Even more tedious code bloat.
With the method above, I have all the facade / unit of work support code stuffed into a reusable class library and all I have to do is write my facade code, which is ONLY concerned with code that actually does something - and it works with multiple contexts.
Works for me... ooh and don't lambast me on the use of the word 'facade'. I never really went to school ;)
Thanks,
Richard
P.s. Have a great weekend!