实体框架 ObjectContext 分享 - 优缺点

2024-02-21

在我的项目中,我使用实体框架 4.0 作为 ORM 将数据保存在 SQL Server 中。

我的项目是应用程序的功能区,主窗体中有网格视图和导航树,其顶部有功能区面板。我的应用程序基本上是一个 CRUD UI,几乎没有业务逻辑。

第一次使用 EF,我通过在编排表单(主表单或向用户显示为应用程序的表单)中创建并保存 objectContext 实例作为成员变量来开发此项目,并将查询绑定到网格视图。

对于各种事件,例如功能区面板按钮单击、网格视图行单击等,我打开另一个窗口窗体。在该窗口窗体中,我创建另一个对象上下文并将其存储在该窗体类的成员变量中。

我读过一些博客和问题,例如:

  1. 如何决定对象上下文的生命周期 http://blogs.msdn.com/b/alexj/archive/2009/05/07/tip-18-how-to-decide-on-a-lifetime-for-your-objectcontext.aspx
  2. Entity Framework 和 ObjectContext n 层架构 https://stackoverflow.com/questions/9262011/entity-framework-and-objectcontext-n-tier-architecture etc.

一组作者建议共享对象上下文,而其他作者则建议短期且不共享。

我达到了这种混乱的状态,因为我现在处于这样一种状态:我在一个子表单中对 objectContext 所做的更改没有反映显示它的父表单。我尝试刷新但仍然没有任何用处。只是为了一个实验,我通过构造函数注入共享了我首先在最父类中创建的objectContext,并且解决了我的更改反射问题。

将所有子表单转换为共享 objectContext 对我来说是一项艰巨的工作。但如果值得的话我已经准备好了。不知道分享起来会存在哪些潜在的问题?

我可能会选择 objectContext 的静态实例,因为我没有将其用于 Web,也没有计划多线程场景。如果需要,我可以成为单身人士。

我的问题:

  1. 根据我的情况共享还是不共享 ObjectContext?
  2. 如果不分享,我如何解决目前用其他对象上下文中所做的更改更新一个对象上下文的问题?
  3. 如果分享 - 哪个会更好?静态还是单例还是其他什么?

项目及环境详情如下:

  • Winforms
  • C#
  • VS 2012
  • EF 4.0,使用数据优先方法创建的模型。

我在搜索和阅读许多问题和博客文章后发布此内容。我读得越多,它就变得越混乱:)如果我让某人假设一些事情需要回答,请耐心等待。如果通过评论提出此类澄清,我将尝试更新问题。


你的问题

根据我的情况共享还是不共享 ObjectContext?不要分享您的背景。 EntityFramework 上下文应遵循 UnitOfWork 模式。您的对象上下文应该尽可能短,而不会不必要地创建/销毁太多上下文。这通常会转化为应用程序中作为工作单元的各个“操作”。对于网络应用程序/API,这可能是HttpWebRequest,或者您可以针对每个逻辑数据操作执行此操作(对于每个已实现的“业务逻辑”部分)。

例如:

  • LoadBusinssObjects()将创建一个上下文,加载您的数据列表以及您想要的任何相关数据,然后处理该上下文。
  • CreateBusinessObject()将创建一个上下文,创建某个实体的实例,用数据填充它,将其附加到上下文中的收集,保存更改,然后处理上下文。
  • UpdateBusinessObject()将从上下文中读取一些对象,更新它,保存更改并处理上下文。
  • DeleteBusinessObject()将在上下文中找到业务对象,将其从上下文中的集合中删除,保存更改并处置上下文。

如果不分享,我如何解决目前用其他对象上下文中所做的更改更新一个对象上下文的问题?这是一份工作发布/订阅架构 http://msdn.microsoft.com/en-us/library/ff649664.aspx。这可以很简单,只需在对象上为上面实现的每个操作添加一些静态事件处理程序即可。然后,在每个业务操作的代码中,触发相应的事件。

如果分享 - 哪个会更好?静态还是单例还是其他什么?这是不正确的。随着上下文的状态管理器不断收集缓存的对象(附加的和未附加的),EF 上下文的内存占用将继续增长。每一次互动你在你的应用程序中所做的。上下文并不是为了这样工作而设计的。

除了资源使用之外,EF 上下文也不是线程安全的。例如,如果您希望允许编辑器表单之一在树列表加载一些新数据的同时保存一些更改,该怎么办?对于一个静态实例,您最好确保这一切都在 UI 线程上运行或与信号量同步(恶心,恶心 - 不好的做法)。

Example

这是一个根据您的帖子使用 C# 和代码优先方法的示例。请注意,为了使示例简短,我不会讨论数据并发或线程之类的问题。此外,在实际应用程序中,这个概念是通过泛型和反射来实现的,以便我们所有的模型都有用于创建、更新、删除的基本事件。

public class MyCodeFirstEntityChangedArgs : EventArgs
{
    /// <summary>
    /// The primary key of the entity being changed.
    /// </summary>
    public int Id {get;set;}

    /// <summary>
    /// You probably want to make this an ENUM for Added/Modified/Removed
    /// </summary>
    public string ChangeReason {get;set;}
}

public class MyCodeFirstEntity
{
    public int Id {get;set;}
    public string SomeProperty {get;set;}

    /// <summary>
    /// Occurs when an instance of this entity model has been changed.
    /// </summary>
    public static event EventHandler<MyCodeFirstEntityChangedArgs> EntityChanged;
}

public class MyBusinessLogic
{
    public static void UpdateMyCodeFirstEntity(int entityId, MyCodeFirstEntity newEntityData)
    {
            using(var context = new MyEFContext())
            {
                // Find the existing record in the database
                var existingRecord = context.MyCodeFirstEntityDbSet.Find(entityId);

                // Copy over some changes (in real life we have a 
                // generic reflection based object copying method)
                existingRecord.Name = newEntityData.Name;

                // Save our changes via EF
                context.SaveChanges();

                // Fire our event handler so that other UI components 
                // subscribed to this event know to refresh/update their views.
                // ----
                // NOTE: If SaveChanges() threw an exception, you won't get here.
                MyCodeFirstEntity.EntityChanged(null, new MyCodeFirstEntityChangedArgs()
                {
                    Id = existingRecord.Id,
                    ChangeReason = "Updated"
                });
            }
    }
}

现在,您可以从任何地方将事件处理程序附加到模型(它是静态事件处理程序),如下所示:

MyCodeFirstEntity.EntityChanged += new EventHandler<MyCodeFirstEntityChangedArgs>(MyCodeFirstEntity_LocalEventHandler);

然后在每个视图中都有一个处理程序,每当触发此事件时,该处理程序都会刷新本地 UI 视图:

static void MyCodeFirstEntity_LocalEventHandler(object sender, MyCodeFirstEntityChangedArgs e)
{
    // Something somewhere changed a record! I better refresh some local UI view.
}

现在,您拥有的每个 UI 组件都可以订阅对其重要的事件。如果您有一个树列表,然后有一些编辑器表单,则树列表将订阅任何更改以添加/更新/删除节点(或简单的方法 - 只需刷新整个树列表)。

应用程序之间的更新

如果您想更进一步,甚至在连接的环境中链接应用程序的单独实例,您可以使用类似的方法通过网络实现发布/订阅事件系统WebSync - Microsoft 技术堆栈的 Comet 实现 http://www.frozenmountain.com/websync/。 WebSync 具有内置的所有功能,可将您想要订阅或发布的每个实体/事件的事件分离到逻辑“通道”中。是的,我在开发 WebSync 的软件公司工作 - 他们为我撰写本文时的时间付费。 :-)

但是,如果您不想为商业实现付费,您可以编写自己的 TCP 套接字客户端/服务器,以便在实体更改时分发上述事件的通知。然后,当订阅应用程序通过网络获取通知时,它可以以相同的方式触发其本地事件处理程序,这将导致本地视图刷新。您无法使用架构不佳的数据上下文静态实例来执行此操作(您将只能运行一个应用程序实例)。通过早期的一些良好设置,您可以轻松地在以后添加分布式发布-订阅系统,该系统可以同时跨本机应用程序和 Web 应用程序的多个实例运行!这变得非常强大。

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

实体框架 ObjectContext 分享 - 优缺点 的相关文章

  • 使用实体框架 4.3 的过滤器加载导航属性

    几天前我放了一个question https stackoverflow com questions 11168505 auditing a table with ef code first关于映射两个类Message and Messag
  • 实体框架代码优先开发资源和文档

    我知道 EF4 仍在开发中 但作为该主题的新手 我需要使用 EF 4 代码优先方法的文档 教程等 所有信息都位于 EF 4 团队博客中 但分散在不同的帖子中 全面覆盖真的很好 有人知道有这样一个地方吗 迄今为止我见过的最好的在线资源是斯科特
  • 如何将 Entity Framework 4.0 与 Xml 或内存存储(非 SQL)结合使用

    如何为实体框架模型指定 Xml 或仅指定内存存储 连接字符串需要提供程序 通常是 SQL 提供程序字符串 但它不会让我忽略提供者 我意识到我可以完全抛弃设计器生成的对象并采用纯 POCO 但随后我必须实现自己的序列化层 可以做到这一点 但对
  • 升级到 EF 6.1.1 使[NotMapped]效果消失

    我已经从 EF 4 3 1 升级到 6 1 1 现在看来注释 NotMapped 没有用了 是的 我已经更改了正确的程序集 并且编译时一切看起来都很好 在存在 NotMapped 的任何地方 该属性都被作为域属性处理 并且我收到一条错误 指
  • 找不到实体框架 4 注释

    我正在尝试使用注释将 POCO 类映射到我的数据库表 我需要使用Table注释来指定我的表的名称 但我无法解析Table注解 注 我导入了System Data Entity命名空间 但它不起作用 我必须导入哪个命名空间才能使用 EF 注释
  • asp.net mvc 模型与实体框架模型

    在 asp net mvc model 文件夹中创建模型是最佳实践吗 将这些模型与您的视图结合使用 并使用服务层将我的模型 调整 为 EF 模型 或者您是否使用过其他方法 这种方法的问题在于 大多数时候我的 自制 模型是 EF 模型的副本
  • 如何将Entity框架中的DbSet转换为ObjectQuery

    我正在使用 Code First 方法 并遇到一个需要将 DbSet 转换为 ObjectQuery 的问题 这就是我为转换所做的 ObjectContext objectContext IObjectContextAdapter db O
  • 实体框架 4 中的唯一键

    现有的数据库模式具有唯一的非主键以及一些依赖它们的外键 是否可以在 Entity Framework v4 中定义唯一键 不是主键 如何 实体框架6 1现在支持数据注释和 Fluent API 的唯一性 数据注释 参考 http msdn
  • 使用 EF4 将 Int32 转换为 Oracle number(5)

    我正在将 EF 4 数据库优先 完全由它生成的模型 与 Oracle 10g 数据库一起使用 并且我在一个字段上遇到问题 我的字段定义为NUMBER 5 在我的数据库中 在我的模型中 EF 将其定义为short 我的问题是我有一些值大于 3
  • EntityConnection 和打开的 SqlConnection

    我有一个关于采用 CodeFirst 方法的 EntityFramework 的问题 基于 EntityConnection 源代码和文档 我无法使用已打开的 SqlConnection 创建它 它要求应该关闭 我们有一些不同的数据库数据层
  • 实体框架代码优先和连接字符串

    我有一个使用 Entity Framework Code First 的小型 MVC 3 应用程序 并为模型使用此连接字符串 data source SQLEXPRESS Integrated Security SSPI AttachDBF
  • 实体框架 4.0:添加缩放器属性会出现错误(未映射的属性:11009)?

    我想向我的模型 表 之一添加一个新属性 基本上它是数据库中不存在的属性 但我需要将其添加到我的模型中 以便自定义生成工具 自跟踪实体生成器 将在自定义生成的文件中创建属性 我添加了一个缩放器属性 它是一个字符串 名为 testme 但它给了
  • 如何将SQL用户自定义函数添加到实体框架中?

    我可以像在 dbml 中那样向 edmx 文件添加 SQL 函数吗 如果可以的话 我该怎么做 如果我不能 有什么解决方法吗 我尝试谷歌 但找不到任何关于如何做到这一点的具体答案 根据给定的答案 我创建了一个存储过程并尝试添加 导入函数 但它
  • 实体框架 - 仅加载选定的属性

    我没有 EF 的实际经验 因此不知道这个问题的相关性 假设我有名为 Student 的表 StudentId Name Username Address DOB DeptId NavigationProp1Id 和 Department 表
  • 使用 Entity Framework 4 删除对象的最简单方法

    确认 我是实体框架的新手 正在尝试找到删除项目的最简单方法 我有一个列表框 其数据源设置为数据库中的 TagCategory 对象 这工作正常 现在我想删除所选项目 所以我做了这样的事情 TagCategory category TagCa
  • 如何更新实体?

    我之前有一个更详细的问题 但我没有答案 我将以更简单的方式提出同样的问题 I have an EF database with foreign key to another table 我想UPDATE an ENTITY 但我需要这样 我
  • 如何避免实体框架 TPT 继承中的多态行为,以便有效地查询基类型

    Overview 我首先使用实体 框架 4 3 代码和流畅的界面来设置我的 DbContext 我有一个基地Item具有继承此类型的其他类型的类 例如Event BlogPost 论坛主题 WikiPage等等 这些继承的类型与我认为实体框
  • 生成实体密钥

    我第一次对 Entity Framework 4 感到失望 事实证明 当 SQL CE 与 EF4 一起使用时 不支持自动生成主键 http social msdn microsoft com forums en US sqlce thre
  • 使用 wcf ria 时有没有办法选择性地跳过 silverlight 字段验证?

    我有一个 可能很常见 的情况 我想重用同一个类来添加新实体并在我的 silverlight 应用程序 SL4 WCF RIA EF4 Linq to Entities 中编辑现有实体 添加新验证器时 我希望自定义验证器检查唯一性 如果不唯一
  • 实体框架 4.1:重写 IEnumerable 验证

    public abstract class Animal IValidatableObject public string Id get set public string Name get set public virtual IEnum

随机推荐

  • 如何更改 Windows 控制台应用程序中的文本或背景颜色

    哪个 C 函数更改文本或背景颜色 MS Visual studio 例如cout lt lt This text 如何将 此文本 设为红色 您可以使用 Win32 更改控制台应用程序的颜色 以下是有关如何操作的示例 include stda
  • 关于 WSO2 API Manager 数据源

    我现在正在执行 WSO2 API 管理器 Analytics 2 0 POC 当我将数据源从 H2 更改为 Oracle 时 在 wso2am 2 0 1 SNAPSHOT 中 有 2 个数据源配置文件 master datasources
  • EF EntityCollection 中的更改通知

    在 Silverlight 4 项目中 我使用 WCF RIA 服务 MVVM 原则和 EF 4 我遇到了这种情况 创建了一个名为 Category 的实体和另一个名为 CategoryLocale 的实体 使用 VS 自动执行 没有 PO
  • 修复 Tomcat 8 上的错误代码:ssl_error_no_cypher_overlap

    我有一个便宜的 SSL 证书 我想用 Tomcat 8 0 26 配置它 我在 Linux 上运行以下命令来创建密钥库 root cert keytool import alias root keystore tomcat jks trus
  • 为哈希选择合适的表大小

    如果我有一个 1000 个键集 我的哈希表的合适大小是多少 如何确定 它取决于负载系数 表将增加其大小并重新分布其元素的 满百分比 点 如果您知道正好有 1000 个条目 并且该数字永远不会改变 则只需将负载因子设置为 1 0 将初始大小设
  • 使用 VBA 删除 Excel 中的工作表和数据透视表

    我正在尝试在 VBA 中集成功率枢轴和枢轴图表的创建 并已经完成了很大一部分 然而 我遇到了一个我似乎无法克服的问题 我创建新的工作表 在其中创建数据透视并将其导出为 PDF 完成后 我删除数据透视表和工作表 Sub DeleteAllPi
  • 在 Python 中测试所有组合

    我有两组选择 optionList1 a1 a2 a3 an optionList2 b1 b2 b3 bn 选项列表中的元素数量不一定相等 我必须从第一个选项列表中选择两次 如何确保我已尝试了第一个列表中的 2 个选项和第二个列表中的一个
  • 如何从外部函数更改局部静态变量值

    include
  • JQuery .ressized,如何为alsoResize属性选择子级

    我有弹出的窗口 可以拖动和调整大小 一切都很好 除了我需要调整大小窗口来调整其中的 div 大小 这可以通过设置轻松完成alsoResize selector 但是 此窗口的每个实例都具有相同的 div 和相同的类名 如果调整一个窗口的大小
  • openOptionsMenu 不适用于全屏

    我有一个全屏模式的活动 android theme android style Theme NoTitleBar Fullscreen 我用按钮打开选项菜单 dmenu setOnClickListener new OnClickListe
  • ggsurvplot - 轴交叉于 0,0

    Survminer产生不错的情节 但有没有办法进一步改变常规的结果ggplot 命令 我尝试做的是使 y 轴从原点开始 如上所述here https stackoverflow com questions 13701347 force th
  • 使用 ObjectDB 搜索空用户数据库时出现问题

    我正在创建一个 java 应用程序 它使用 ObjectDB 来创建和维护一组数据库 我目前正在尝试实现一个数据库来存储由用户名和密码字符串组成的用户对象 在 JFrame swing 类上 我有一个用于创建新用户的按钮 单击此按钮时 我希
  • 通过周围像素的平均值去除图像中的孔

    任何人都可以帮助我用从相邻非零像素获取的值来填充这些黑洞 谢谢 做到这一点的一个好方法是解决线性热方程 http en wikipedia org wiki Heat equation 你要做的就是修复好区域像素的 温度 强度 让热量流入坏
  • 基本 Node.js 项目的“属性‘程序’不存在”

    我创建了简单的node js应用程序 源代码来自这里https azure microsoft com en us blog visual studio code and azure app service a perfect fit ht
  • 明显的 BufferBlock.Post/Receive/ReceiveAsync 竞赛/bug

    交叉发布到http social msdn microsoft com Forums en US tpldataflow thread 89b3f71d 3777 4fad 9c11 50d8dc81a4a9 http social msd
  • 如何使 Onboarding 与 iOS13 中的 Scene Delegate 配合使用?

    我正在尝试在 SceneDelegate 中设置我的入门屏幕 当我运行下面的代码时 它可以编译 但只是进入黑屏 其中有很多针对 AppDelegate 的精彩入门教程 但针对 iOS13 的新 SceneDelegate 的入门教程却很少
  • 如何查看 /bin/sh 指向的内容

    我正在阅读 bin sh 和 bin bash 之间的差异 并遇到了这个有趣的问题 答案 here https stackoverflow com questions 5725296 difference between sh and ba
  • PHP:如果!空&空

    所以我有这个表格 有2个字段 Youtube 和 链接 我想做的如果已经填写了YouTube 应该这样做 if empty youtube if pos false echo Du skal indtaste youtube et URL
  • 目前的iphone版本是否支持彩信? [复制]

    这个问题在这里已经有答案了 可能的重复 是否可以使用 iPhone SDK 发送图片消息 https stackoverflow com questions 5150271 is it possible to send a picture
  • 实体框架 ObjectContext 分享 - 优缺点

    在我的项目中 我使用实体框架 4 0 作为 ORM 将数据保存在 SQL Server 中 我的项目是应用程序的功能区 主窗体中有网格视图和导航树 其顶部有功能区面板 我的应用程序基本上是一个 CRUD UI 几乎没有业务逻辑 第一次使用