3

Je voulais simplement savoir ce que les autres font pour gérer leur contexte lors de l'utilisation d'EF4. Je crée une application MVC, en utilisant (je pense :)) l'unité de travail, la couche de service, le référentiel, la technique EF4 w/POCO.Entity Framework 4 Contexte?

Mes contrôleurs utilisent des services qui prennent un UOW, qui utilisent ensuite des référentiels pour obtenir des POCO de l'EF.

Est-ce implémenté correctement?

Regardez ci-dessous, et tout commentaire est apprécié !!

Contrôleur

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é de travail

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 

dépôt

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

à partir de votre résumé cela semble à peu près juste, j'utilise similaire - en plus de la faute de frappe dans votre 'Committ()' méthode ;-) – BrokenGlass

Répondre

2

Permettez-moi de vous dire, j'agonisé sur l'approche à adopter depuis longtemps, la plupart du temps sur StackOverflow :)

je me suis installé sur une mise en œuvre de cet article bien sur gérer le contexte de l'objet (prendre note de la version modifiée permettant plusieurs contextes).

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

Je mis en œuvre comme façades:

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); 
    } 
} 

Bien sûr, il est vieux mais le garçon oh boy, ça marche! Vous voyez, la chose avec toutes ces couches de service/unité de travail/dépôt est que vous devez écrire beaucoup de code pour le supporter (et EF4 était censé réduire le gonflement du code!) . Chaque fois que vous ajoutez une nouvelle entité, devinez quoi? Encore plus de gonflement de code fastidieux. Avec la méthode ci-dessus, j'ai tout le code de façade/unité de support de travail bourré dans une bibliothèque de classe réutilisable et tout ce que j'ai à faire est d'écrire mon code de façade, qui concerne SEULEMENT le code qui fait quelque chose - et cela fonctionne avec plusieurs contextes.

Fonctionne pour moi ... et ne me gêne pas sur l'utilisation du mot «façade». Je ne ai jamais vraiment allé à l'école;)

Merci, Richard

P.S. Passe un bon weekend!