ASP.NET Session 对象中的实体框架对象上下文?

2023-11-21

我们有一个多层的 Asp.NET Web 窗体应用程序。数据层有一个类叫做DataAccess它实现了IDisposable并有一个实体框架对象上下文的实例作为私有字段。该类具有许多返回各种实体集合的公共方法,并且在释放其对象上下文时将释放它。

由于我们面临的许多问题,我们认为保留对象上下文(或对象的实例)将是一个很大的优势DataAccess)在服务器上的范围更长。有人建议在HttpContext.Current.Items收集自这个帖子为了每个 Http 请求都有一个实例。

我想知道的是:将对象上下文的实例存储在HttpContext.Current.Session目的????

  • 我假设 Session 对象已完成并在用户会话过期时设置为垃圾回收,因此该实例将被正确处理。
  • 我假设大多数默认浏览器设置都会让我们的应用程序毫无疑虑地放置其 SessionId cookie。
  • 对象上下文将处理的数据量并不大,并且不会对我们像样的服务器硬件造成问题,因为随着时间的推移缓存和相对较少的并发用户。

这实施起来会相对较快,并且不会影响我们许多现有的单元测试。

我们将使用 AutoFac 和 ServiceProvider 类来提供实例。当需要 ObjectContext 的实例时,它将由类似于以下的代码返回:

private static Entities GetEntities(IContext context)
{
    if (HttpContext.Current == null)
    {
        return new Entities();
    }

    if (HttpContext.Current.Session[entitiesKeyString] == null)
    {
        HttpContext.Current.Session[entitiesKeyString] = new Entities();
    }

    return (Entities)HttpContext.Current.Session[entitiesKeyString];
}

Cheers.


存储一个ObjectContext在会话状态中,我认为不是一个好的实践,因为该类旨在封装工作单元模式 - 您加载一些数据(实体),修改它们,提交您的更改(由UOW),然后就完成了。 UOW 对象并非旨在或设计为长期存在的。

也就是说,它can要在不造成任何重大灾难的情况下完成,您只需确保了解幕后发生的事情即可。请继续阅读如果您打算这样做,这样您就知道自己将面临什么并意识到权衡。


我假设 Session 对象已完成并在用户会话过期时设置为垃圾回收,因此该实例将被正确处理。

这实际上是不准确的,或者至少看起来是基于其措辞方式。会话到期/注销不会立即导致任何项目被处置。他们会最终被最终确定/处置,但这取决于垃圾收集器,您无法控制它何时发生。这里最大的潜在问题是,如果您碰巧手动打开了连接ObjectContext,它不会自动关闭 - 如果你不小心,你可能最终会泄漏数据库连接,这是常规单元测试/集成测试/实时测试无法发现的。

对象上下文将处理的数据量并不大,并且不会对我们像样的服务器硬件造成问题,因为随着时间的推移缓存和相对较少的并发用户。

请记住,增长是无限的。如果某个特定用户决定连续 12 个小时使用您的网站并整天运行不同的查询,那么上下文将会变得越来越大。一个ObjectContext没有自己的内部“垃圾收集”,它不会清除长期未使用的缓存/跟踪实体。如果您根据您的用例确定这不会成为问题,那么很好,但应该困扰您的主要问题是您缺乏control的情况。


另一个问题是线程安全。ObjectContext不是线程安全的。会话访问通常是序列化的,因此一个请求将阻塞等待其会话状态,直到同一会话的另一请求完成。但是,如果有人决定稍后进行优化,特别是页面级只读会话的​​优化,请求将不再持有独占锁,并且最终可能会遇到各种竞争条件或重入问题。

最后但并非最不重要的当然是多用户并发问题。一个ObjectContext永远缓存其实体,直到它被处置。如果另一个用户自己更改相同的实体ObjectContext,第一个的所有者ObjectContext will never了解这一变化。这些过时的数据问题可能非常难以调试,因为您实际上可以看到查询进入数据库并返回新数据,但是ObjectContext将用缓存中已有的旧数据覆盖它。在我看来,这可能是避免长期存在的最重要原因ObjectContext实例;即使您认为您已对其进行编码以从数据库中获取最新数据,ObjectContext会认为它比你聪明,然后把旧实体还给你。


如果您了解所有这些问题并已采取措施缓解这些问题,那就好了。但我的问题是,为什么您认为会话级ObjectContext这是个好主意吗?创建一个ObjectContext这确实是一个非常便宜的操作,因为元数据是为整个 AppDomain 缓存的。我敢打赌,要么你错误地认为它很昂贵,要么你试图在几个不同的网页上实现复杂的有状态进程,而后者的长期后果比任何特定的后果都要糟糕得多简单地放置一个可能会造成的伤害ObjectContext进入会话。

如果你无论如何都要继续做这件事,只要确保你这样做是出于正确的理由,因为没有太多充分的理由这样做。但是,正如我所说,这绝对是可能的,并且您的应用程序不会因此而崩溃。


Update- 对于任何其他考虑对此进行否决的人,因为“同一会话上的多个请求可能会导致线程安全问题”,请阅读底部ASP.NET 会话状态概述文档。这不仅仅是个人访问序列化的会话状态;任何获取会话的请求都会对该会话保留独占锁,直到整个请求完成后才会释放该锁。除了我上面列出的一些优化之外,在默认配置中不可能有两个同时请求持有对同一会话本地实例的引用。ObjectContext.

我仍然不会存储ObjectContext由于上面列出的几个原因,它处于会话状态,但这不是线程安全问题,除非您将其设为一个。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ASP.NET Session 对象中的实体框架对象上下文? 的相关文章

随机推荐

  • 将表转换为分层字典?

    我有一个表格 A1 B1 C1 value A1 B1 C1 value A1 B1 C2 value A1 B2 C1 value A1 B2 C1 value A1 B2 C2 value A1 B2 C2 value A2 B1 C1
  • 瘦服务器:将 Rails 应用程序日志输出到控制台,如“rails s”那样

    我需要跑thin start or thin ssl start在我的 Rails 应用程序的根目录中 并查看输出到控制台的应用程序日志 类似于rails s does In config ru文件 位于应用程序的根目录 在该行之前添加以下
  • 授予 Node.js 访问证书/私钥的权限

    我正在尝试在我的 Node js 应用程序上使用 HTTPS 就像它已针对其他任何内容启用一样 我已经安装了密钥和证书 但我得到了Error EACCES permission denied当我试图在应用程序上指向它们时 密钥和证书都位于以
  • 是否可以保证 memset 将结构中的填充位清零?

    一般来说 根据 C 标准 是否可以保证带有 0 的 memset 会将 C 结构中的填充位清零 海湾合作委员会呢 例如 类似 struct MyStruct unsigned char member1 unsigned int member
  • 在 viewpager 中显示 Youtube 视频

    我想设置YouTube内的视频ViewPager 为此我设置了FrameLayout在适配器中 我在其中设置了 YoutubeVideoFragment 如下所示 我的 ViewPager 适配器 import android app Ac
  • 在 Go 中使用匿名成员扁平化编组 JSON 结构

    给出以下代码 转载于此处play golang org package main import encoding json fmt type User struct Id int json id Name string json name
  • 在 ggplot 中使用多个尺寸比例

    我正在尝试构建一个显示从一个类到另一个类的转换的图 我想要有代表根据类属性调整大小的每个类的圆圈 以及根据从一个类到另一个类的转换数量从一个类到另一个类的箭头 举个例子 library ggplot2 points lt data fram
  • php - 如何检索 div 标签属性值

    我有一个可以隐藏或不隐藏的 div 具体取决于用户 该 div 有一个名为 attrLoc 的属性 我想要的是能够从 php ini 检索该属性值 希望有人能帮忙 预先感谢您的回复 干杯 马克 My HTML div class hidde
  • 在行内行块下方添加一个 div

    我有一个内联块元素列表 它们换行形成几行 我想在行之间显示一个 div 元素 具体取决于特定元素所在的位置 例如 前几行已编号 如果我想定位第三个元素并显示全长元素 包含块的 div 的 100 那么它将如下所示 对于任何块 1 5 全长
  • 如何将地图转换为 url 查询字符串?

    您是否知道任何实用程序类 库可以将 Map 转换为 URL 友好的查询字符串 Example 我有一张地图 param1 12 param2 cat 我想得到 param1 12 param2 cat 最终输出 relativeUrl pa
  • java和javaw的区别

    我搜索以了解之间的区别java exe and javaw exe 我通读了Java exe 和 Javaw exe 之间的区别 那里指出java exe用于控制台和javaw exe用于窗口应用程序 在其他一些帖子中提到控制台不可用jav
  • 具有延迟加载功能的单元素枚举类型单例

    我读了很多关于在 java 中实现单调模式的不同风格的论坛和帖子 似乎 枚举是在 java 中实现单调模式的最佳方法 我想知道如何使用 Java Enum 在 java 中实现 SingleTone 模式带有延迟加载能力 因为枚举只是类 第
  • 使用 Maven 将 Dll 打包在 Jar 中 - 单一目标

    我在我的 Maven 项目中添加了一个 DLL 作为依赖项 如下所示
  • Google Drive Rest API:未经身份验证的使用已超出每日限制。继续使用需要注册

    我正在将我的应用程序从已弃用的 Google Drive Android API 迁移到 Drive Rest API 我使用新包实现了所需的行为 并且在模拟器中一切正常 应用程序要求访问用户的云端硬盘并让它上传文件 当我开始在真实设备上测
  • 使用 JNA 单击鼠标

    我正在尝试使用 JNA 模拟鼠标在窗口中的单击 public class App public static final int WM LBUTTONUP 514 public static final int WM LBUTTONDOWN
  • 使用 ASP.NET Core 获取绝对 URL

    在 MVC 5 中 我使用以下扩展方法来生成绝对 URL 而不是相对 URL public static class UrlHelperExtensions public static string AbsoluteAction this
  • 什么是回调函数以及如何在 OOP 中使用它

    我想使用php 简单的 HTML DOM 解析器从充满文章的页面上的每篇文章中获取图像 标题 日期和描述 当查看 API 时 我注意到它有一个 set callback 来设置回调函数 但是我不确定它的作用或我将如何使用它 在其中一个示例中
  • 使用 unique_ptr 作为值初始化静态 std::map

    如何初始化静态地图 其中值是std unique ptr static void f static std map
  • 在 ruby​​ on Rails 中被 nokogiri 转换为“\u0092”

    我有一个 html 页面 其中包含一些 html 实体 例如 Here I am not pasting whole html page content just putting issue line only html file p th
  • ASP.NET Session 对象中的实体框架对象上下文?

    我们有一个多层的 Asp NET Web 窗体应用程序 数据层有一个类叫做DataAccess它实现了IDisposable并有一个实体框架对象上下文的实例作为私有字段 该类具有许多返回各种实体集合的公共方法 并且在释放其对象上下文时将释放