实体框架 4 上下文?

发布于 2024-10-19 19:02:02 字数 5576 浏览 1 评论 0原文

我只是在寻找其他人在使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

甜中书 2024-10-26 19:02:02

让我告诉你,我很长一段时间都在苦恼该采取什么方法,主要是在 StackOverflow 上:)

我决定实现这篇关于管理对象上下文的好文章(请注意允许多个上下文的修订版本)。

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 应该减少代码膨胀!)。每次添加新实体时,你猜怎么着?甚至更加繁琐的代码膨胀。

通过上面的方法,我将所有外观/工作单元支持代码填充到可重用的类库中,我所要做的就是编写我的外观代码,该代码只涉及实际执行某些操作的代码 - 并且它适用于多个上下文。

对我有用...哦,不要因为我使用“外观”这个词而责备我。我从来没有真正上过学;)

谢谢,
理查德·

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:

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

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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文