3

我只是想了解其他人在使用EF4時如何管理其上下文。我正在創建一個MVC應用程序,使用(我認爲:))工作單元,服務層,存儲庫,EF4 w/POCO技術。實體框架4上下文?

我的控制器使用的服務採用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 
+1

從您的摘要中聽起來是正確的,我使用類似的 - 除了'Committ()'方法中的錯字外;-) – BrokenGlass 2011-02-28 23:55:04

回答

2

讓我告訴你,我苦苦思索什麼辦法採取了很長一段時間,主要是在計算器上:)

我在這個美好的文章的實施對解決管理對象上下文(注意允許多個上下文的推薦版本)。

http://dotnetslackers.com/articles/ado_net/Managing-Entity-Framework-ObjectContext-lifespan-and-scope-in-n-layered-ASP-NET-applications.aspx

然後,我實現外立面像:當然

public class MyEntityFacade : FacadeBase<MyEntities, MyEntity> 
{ 
    public object GetAll() 
    { 
     return this.ObjectContext.MyEntities.ToList(); 
    } 

    public bool HasChild(int parentId) 
    { 
     return this.ObjectContext.MyEntityChild.Any(c => c.parentId == parentId); 
    } 
} 

,這是舊的,但男孩男孩哦,它的作品!

看到,具有所有服務層/工作單元/存儲庫的東西的東西,你最終不得不寫很多代碼來支持它(當然EF4應該減少代碼膨脹!) 。每當你添加一個新的實體時,你猜怎麼着?更繁瑣的代碼膨脹。

使用上面的方法,我將所有外觀/工作單元支持代碼填充到可重用的類庫中,我所要做的就是編寫我的外觀代碼,它只關注實際執行某些操作的代碼 - 它適用於多個上下文。

適用於我......哦,並且不要使用「門面」一詞來誇耀我。我從來沒有真正去學校;)

感謝, 理查德

附:週末愉快!