n 层项目中的实体框架 ObjectContext 生命周期

     2023-04-13     103

关键词:

【中文标题】n 层项目中的实体框架 ObjectContext 生命周期【英文标题】:Entity Framework ObjectContext lifetime in an n-tier project 【发布时间】:2015-06-30 16:36:34 【问题描述】:

我目前正在为客户构建一个大型解决方案,其中代码可重用性是关键字,因为不同类型的项目(即网站、WCF 服务、WPF 等)应该使用完全相同的业务逻辑。

现在,我的解决方案如下所示:

业务逻辑层(定义业务规则的所有逻辑都在这里添加) 接口 模型(ViewModel、DTO 等) 存储库(当前使用 Entity Framework 6。这是所有数据库事务所在的位置) Web 服务(WCF 服务) MVC 网站

关键是任何表示层(即 MVC 网站)都将使用业务逻辑层,然后使用存储库进行所需的任何数据库事务。

虽然这按我想要的方式工作,但我发现自己一直在与实体框架中的 ObjectContext 作斗争,这仅仅是因为在查询存储库中的数据时,实体不会转移到业务逻辑(这是合乎逻辑的,因为EF 延迟加载)我知道我可以使用.Include(x => x.MyOtherTable),但由于数据库相当大,这种方法很快就会变得臃肿,如果包含的表有很多记录,查询可能会相当大。

然后我创建了一个 DbContextManager 类,如下所示:

public static class DbContextManager

    //Unique context key per request and thread
    private static string Key
    
        get
        
            return string.Format("MyDb_01", HttpContext.Current.GetHashCode().ToString("x"), Thread.CurrentContext.ContextID);
        
    

    //Get and set request context
    private static MyEntities Context
    
        get  return HttpContext.Current.Items[Key] as MyEntities ; 
        set  HttpContext.Current.Items[Key] = value; 
    

    //Context per request
    public static MyEntities Current
    
        get
        
            //if null, create new context 
            if (Context == null)
            
                Context = new MyEntities ();
                HttpContext.Current.Items[Key] = Context;
            
            return Context;
        
    

    //Dispose any created context at the end of a request - called from Global.asax
    public static void Dispose()
    
        if (Context != null)
        
            Context.Dispose();
        
    

在我的 global.asax 中,我在请求结束时处理上下文:

private void Application_EndRequest(object sender, EventArgs e)
    
        DbContextManager.Dispose();
    

这很完美,我现在可以在存储库中进行初始数据库调用,然后在我的业务逻辑层中制定业务逻辑规则,这仅仅是因为 ObjectContext 为 http 请求而存在。

但是,当我需要从 WCF 服务项目(或即 WPF 项目)调用相同的业务逻辑方法时,我将无法使用我的 DbContextManager 类,因为它依赖于 HttpContext。

我觉得我现在这样做完全错误,我正在与实体框架进行一场不必要的战斗。我错过了什么? Entity Framework 是否适合这些类型的解决方案?现在肯定不是那种感觉:-)

非常感谢任何帮助或提示!

提前致谢。

【问题讨论】:

看到您的数据库上下文被部署在服务层中真是令人恐惧。为什么不直接在 DAL 中显式加载实体,而不是冒泡延迟查询?也许更有针对性、更小的服务将有助于缓解臃肿,并帮助您避免需要将数据库直接冒泡。 嗨,大卫,感谢您的意见。 “可怕”,这是一个大词;-) 在我的服务层?我不确定你是什么意思。当请求结束时,它会在 MVC 应用程序中释放。在我看来,那里没有服务层。您是否可以制作“显式加载实体”的代码 sn-p ?我不确定这到底是什么意思。 查看我的答案***.com/questions/29637516/…它可能会给你一些想法。 @BoMortensen 很抱歉造成混乱。我在全局 asax 中处理 db 上下文的问题是,您已将数据库完全绑定到 Web 项目 (MVC)。没有关注点分离,也没有控制反转。对我来说,在 n 层应用程序中这是一个非常可怕的地方。至于显式加载实体,每当您使用 ToList、ToArray 等解决查询时,您就是将查询的实体显式加载到内存中。这使您可以在离开 DAL 之前巧妙地处理您的上下文。 大卫:不用担心 :-) 我绝对明白你关于 global.asax 文件的意思。这正是我的问题:它与 DAL 的耦合太紧密了。然后我必须对急切加载进行一些修改,希望它会更有意义;-) 【参考方案1】:

我在这里很困惑。看起来您直接在视图层中使用实体层对象。

这通常是个坏主意。你的模型应该封装这些。您的业​​务逻辑层应该使用您的模型层来构建 UI 层可以生成/使用的 ViewModel 和 DTO 对象。这将允许您将 UI 层与数据库/实体层完全分离。

这将使在 Web 服务层中重用您的业务逻辑变得微不足道。它应该对您的数据库层一无所知。否则,在实体层中添加或更改字段将对所有 UI 层产生直接影响。

【讨论】:

您好,Rob,感谢您的意见。你是对的,我实际上已经制作了一些从实体映射的 DTO。比直接使用实体效果更好。我有点不确定 在哪里 我应该将实体映射到 DTO:在存储库类中还是在业务逻辑层中?你会带什么去? :-) 我通常在业务层做这个。如果您在存储库层执行此操作,则最终会在业务逻辑和视图层之间建立另一个映射层。有些人真的想要这种级别的解耦,理论上他们希望在不更改业务逻辑的情况下更改数据库层,但这很少得到回报(恕我直言)。我已经构建了在两层进行映射的系统,但通常最终感觉像是在浪费时间/精力,并且添加了更多可能出错的映射代码。 加入 DTO 层的另一个很好的副作用是您可以更轻松地支持诸如向后兼容性之类的东西。不将实体暴露给 UI 意味着您可以执行诸如添加具有智能默认值的附加字段之类的操作。这将使您的业务逻辑层随着时间的推移更具弹性。

具有实体框架 6 的 ObjectContext 在现有相关实体上插入重复项

】具有实体框架6的ObjectContext在现有相关实体上插入重复项【英文标题】:ObjectContextwithEntityFramework6insertingduplicatesonexistingrelatedentities【发布时间】:2015-11-1500:01:14【问题描述】:我创建它是为了希望为一些人节省一些浪费的时... 查看详情

如何在实体框架中模拟 ObjectContext 或 ObjectQuery<T>?

】如何在实体框架中模拟ObjectContext或ObjectQuery<T>?【英文标题】:HowtomockObjectContextorObjectQuery<T>inEntityFramework?【发布时间】:2010-09-2917:58:31【问题描述】:如何在实体框架中模拟ObjectContext或ObjectQuery?【问题讨论】:除... 查看详情

N 层服务层验证显示表示层中的业务逻辑错误

...的ASP.NETWeb窗体方式转换为ASP.NETMVC。我有一个正在处理的项目,该项目在数据库中有大约40-50个表。我决定使用实体框架作为我的数据访问层。我还决定在EF 查看详情

N 层应用程序上的实体框架自我跟踪实体

】N层应用程序上的实体框架自我跟踪实体【英文标题】:EntityFrameworkSelfTrackingEntitiesonaN-Tierapplication【发布时间】:2011-08-2212:39:32【问题描述】:这是一个一般性的架构问题,希望对那些已经在最终应用程序中使用EF的人来说。... 查看详情

springboot框架中的dao层entity层service层controller层

一般的项目模块中都有DAO、Entity、Service、Controller层。Entity层:实体层数据库在项目中的类Entity层是实体层,也就是所谓的model,也称为pojo层,是数据库在项目中的类,该文件包含实体类的属性和对应属性的set... 查看详情

我应该如何监听从 ObjectContext 添加/删除的实体?

】我应该如何监听从ObjectContext添加/删除的实体?【英文标题】:HowshouldIlistenforentitiesbeingadded/deletedfromanObjectContext?【发布时间】:2012-01-0815:22:31【问题描述】:据我所知,ObjectContext没有公开任何直接监听添加/删除项目的方法。... 查看详情

ObjectContext.Refresh()?

】ObjectContext.Refresh()?【英文标题】:ObjectContext.Refresh()?【发布时间】:2010-12-1708:16:47【问题描述】:如何更新数据存储中的所有脏实体,并将其更改的值重置为原始存储值?ObjectContext.Refresh方法需要将要刷新的实体作为参数。... 查看详情

分层架构中的 ASP.NET 和实体框架 - 仅将实体框架用于 ORM

】分层架构中的ASP.NET和实体框架-仅将实体框架用于ORM【英文标题】:ASP.NETandEntityFrameworkinLayeredArchitecture-usingEntityFrameworkforORMonly【发布时间】:2010-10-2906:29:14【问题描述】:我有一个使用分层架构的ASP.NET应用程序,例如表示层... 查看详情

如何在类库项目中配置实体框架?

】如何在类库项目中配置实体框架?【英文标题】:HowdoIconfigureEntityframeworkinclassLibraryproject?【发布时间】:2014-10-1321:06:00【问题描述】:我创建了一个类库项目,其中包含实体框架对象,该对象将负责我的多个项目的公共数据... 查看详情

PHP中的代码优先实体框架模型

...】:2016-06-0312:08:50【问题描述】:我最近在一个ASP.NetMVC项目中工作,我们使用代码优先技术来创建所有数据库表。我真的很喜欢这个想法,您无需接触数据库并创建由EF层自动映射到数据库的模型类。我打算用PHP开始一个爱好项... 查看详情

当使用实体框架作为数据访问层时,如何实现业务逻辑层?

...】:2012-08-1803:22:12【问题描述】:假设我有3层第1层:WPF项目(包含:xaml、viewmodels、mvvm框架)第2层:业务逻辑层(包含:普通c#类)第3层:实体框架(包含:存储库 查看详情

向下转换 ObjectContext 到实体集合

】向下转换ObjectContext到实体集合【英文标题】:DowncastObjectContexttoEntitiescollection【发布时间】:2013-08-0718:40:00【问题描述】:我在EF4.0中使用数据库优先方法创建了一个实体模型。我希望能够在没有app.config文件的情况下使用我的... 查看详情

在业务逻辑层使用实体框架生成的类

...2010:57:59【问题描述】:我有一个使用三层架构的ASP.net(C#)项目。我开始在我的DAL中使用实体框架,问题是实体框架生成的类在多大程度上可以在业务逻辑层中使用?直接使用它们是个好主意,还是我应该创建自己的业务对象并从... 查看详情

用实体框架和 POCO 类替换遗留数据层的策略

...间】:2011-08-2910:53:26【问题描述】:我们正在处理的这个项目中使用.netC#4.0、VS2010、EF4.1和遗留代码。我正在开发一个win表单项目,我已决定开始使用实体框架4.1来访问mssqldb。代码库很旧, 查看详情

n 分层架构中的实体框架 - 要遵循的最佳实践?

】n分层架构中的实体框架-要遵循的最佳实践?【英文标题】:EntityFrameworkinantieredarchitecture-BestPracticestofollow?【发布时间】:2010-12-2502:30:48【问题描述】:我一直在阅读MSDN文章http://msdn.microsoft.com/en-us/magazine/cc700340.aspx但想知道在... 查看详情

与 ObjectContext 相比,为啥在 EF 4.1 中插入实体如此缓慢?

】与ObjectContext相比,为啥在EF4.1中插入实体如此缓慢?【英文标题】:WhyisinsertingentitiesinEF4.1soslowcomparedtoObjectContext?与ObjectContext相比,为什么在EF4.1中插入实体如此缓慢?【发布时间】:2011-05-0922:52:41【问题描述】:基本上,我... 查看详情

Dal(带有实体框架)和模型层到 MVC

...6:46:43【问题描述】:首先,我将EF用于Dal层(与MVC分离的项目,相同的解决方案)。从EF的EDMX文件生成的模型是来自Model层的实际模型??如果是这样,我如何访问这些模型以在MVC的View层中工作?我认为直接从视图访问数据层以... 查看详情

每组操作的可重用 ObjectContext 还是新的 ObjectContext?

】每组操作的可重用ObjectContext还是新的ObjectContext?【英文标题】:ReuseableObjectContextornewObjectContextforeachsetofoperations?【发布时间】:2010-11-1802:59:45【问题描述】:我是实体框架的新手,我刚开始在空闲时间玩弄它。我遇到的主要... 查看详情