Entity framework 4 实体框架ObjectContext共享-优缺点

Entity framework 4 实体框架ObjectContext共享-优缺点,entity-framework-4,objectcontext,Entity Framework 4,Objectcontext,在我的项目中,我使用EntityFramework4.0作为ORM在SQLServer中持久化数据 我的项目是应用程序中的一个功能区,主窗体中有一个网格视图和导航树,顶部有功能区面板。我的应用程序基本上是一个CRUD用户界面,几乎没有业务逻辑 作为第一次使用EF,我通过在编排表单(主表单或显示为用户应用程序的表单)中创建并保存objectContext实例作为成员变量来开发此项目,并将查询绑定到网格视图 对于功能区面板按钮单击、网格视图行单击等各种事件,我打开另一个windows窗体。在该窗口窗

在我的项目中,我使用EntityFramework4.0作为ORM在SQLServer中持久化数据

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

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

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

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

  • 等等
  • 一组作者建议共享对象上下文,而另一组则建议使用短期和非共享的上下文

    我之所以达到这种混乱状态,是因为我现在所处的状态是,我对其中一个子表单中的objectContext所做的更改没有反映显示它的父表单。我试图刷新,但仍然没有任何用处。只是为了一个实验,我共享了我第一次通过构造函数注入在大多数父类中创建的objectContext,我的更改反射问题得到了解决

    将所有子表单转换为共享objectContext对我来说是一项艰巨的工作。但如果值得的话,我已经准备好了。我不确定分享它的潜在问题是什么

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

    我的问题:

  • 在我的情况下共享还是不共享ObjectContext
  • 如果不共享,我如何解决当前使用另一个objectContext中的更改更新一个objectContext的问题
  • 如果要分享,哪种方式更好?静态的还是单态的还是其他的
  • 项目和环境详情如下:

    • Winforms
    • C#
    • VS 2012
    • EF 4.0,采用数据优先方法创建的模型
    我在搜索和阅读了许多问题和博客文章后发布了这篇文章。我读得越多,它就越让人困惑:)如果我让别人去假设一些事情来回答,请容忍我。如果通过评论询问此类澄清,我将尝试更新问题。

    您的问题 是否为我的情况共享ObjectContext? 不要分享你的背景。EntityFramework上下文应遵循UnitOfWork模式。对象上下文应该尽可能短,而不会不必要地创建/破坏太多上下文。这通常转化为应用程序中作为工作单元的单个“操作”。对于web应用程序/api,这可能是根据
    HttpWebRequest
    ,也可能是根据逻辑数据操作(针对每个实现的“业务逻辑”)执行的

    例如:

    • LoadBusinssObjects()
      将创建一个上下文,加载数据列表以及所需的任何相关数据,然后处理上下文
    • CreateBusinessObject()
      将创建一个上下文,创建某个实体的实例,用数据填充它,将其附加到上下文中的集合,保存更改,然后处理上下文
    • UpdateBusinessObject()
      将从上下文中读取一些对象,对其进行更新,保存更改,并处理上下文
    • DeleteBusinessObject()
      将在上下文中找到一个业务对象,将其从上下文中的集合中删除,保存更改并处置上下文
    如果不共享,我如何解决当前使用一个objectContext中的更改更新另一个objectContext的问题? 这是一份适合年轻人的工作。对于上面实现的每个操作,这可以简单到在对象上使用几个静态事件处理程序。然后在每个业务操作的代码中触发相应的事件

    如果要分享-哪种方式更好?静态、单态或其他? 这是不正确的。EF上下文的内存占用将继续增长,因为上下文的状态管理器会为应用程序中的每个交互不断收集缓存对象(已连接和未连接)。上下文不是为这样工作而设计的

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

    例子 下面是一个根据您的帖子使用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"
                    });
                }
        }
    }
    
    现在,您拥有的每个UI组件都可以订阅对其重要的事件。如果您有一个树列表和一些编辑器表单,那么树列表将订阅任何更改以添加/更新/删除节点(或者简单的方法-只需刷新整个树列表)

    应用程序之间的更新 如果您想更进一步,甚至在连接的环境中链接应用程序的单独实例,您可以通过网络使用类似的方式实现发布/订阅事件系统。WebSync内置了所有功能,可以将您要订阅或发布到的每个实体/事件的事件分隔成逻辑“通道”。是的,我在一家制作WebSync的软件公司工作,他们为我付费
    static void MyCodeFirstEntity_LocalEventHandler(object sender, MyCodeFirstEntityChangedArgs e)
    {
        // Something somewhere changed a record! I better refresh some local UI view.
    }