C# 在以后而不是在对象的属性更改时通知实体框架上下文有关更改

C# 在以后而不是在对象的属性更改时通知实体框架上下文有关更改,c#,winforms,entity-framework,inotifypropertychanged,C#,Winforms,Entity Framework,Inotifypropertychanged,我有一个简单的ObjectListView,它显示了名为Person的EntityFramework对象中的一些列,以简化事情。我使用实体框架将其加载到ObjectListViews,然后从上下文中将其取消匹配。此人有多个字段,如姓名、姓氏、文件等 考虑到一些文件是5mb-50mb,我不想不需要就将它们加载/保存到数据库中。现在,当有人在ObjectListView中双击时,所选人员将加载到文本框字段中。在编辑任何字段时,我会检查人名或姓氏是否发生了变化,如果发生了变化,我会像下面的代码那样更新

我有一个简单的ObjectListView,它显示了名为Person的EntityFramework对象中的一些列,以简化事情。我使用实体框架将其加载到ObjectListViews,然后从上下文中将其取消匹配。此人有多个字段,如姓名、姓氏、文件等

考虑到一些文件是5mb-50mb,我不想不需要就将它们加载/保存到数据库中。现在,当有人在ObjectListView中双击时,所选人员将加载到文本框字段中。在编辑任何字段时,我会检查人名或姓氏是否发生了变化,如果发生了变化,我会像下面的代码那样更新上下文

    private void test (Person person){
        using (var context = new EntityBazaCRM(Settings.sqlDataConnectionDetailsCRM)) {
            context.Persons.Attach(dokument);
            if (person.Name != nameTextBox.Text) {
                person.Name = nameTextBox.Text;
                context.ObjectStateManager.GetObjectStateEntry(person).SetModifiedProperty("Name");
            }
            if (person.SurName != surNameTextBox.Text) {
                person.SurName = surNameTextBox.Text;
                context.ObjectStateManager.GetObjectStateEntry(person).SetModifiedProperty("SurName");
            }
            context.SaveChanges();
        }

    }
这很有效。。但我想做的实际上不是在用户更改后立即保存更改,而是在最后,当他按下“全部保存”大按钮时,它将遍历所有ObjectListView项,并根据需要在数据库中更新它们。问题是我不能更新上下文并在以后再做,因为上下文在那时不会被使用,但最终在保存所有内容时会被使用

那么我有什么选择呢?我被要求使用,但当我看代码时,我认为它不适合这种情况,或者我根本不知道如何使用它

另一个选项是从数据库中为每列实际创建bool值,如

public partial class Person
{
    public bool NameChanged {get;set; }

    public bool SurnameChanged { get; set; }
}
保存时,我将检查bool是否更改,如果更改,则在保存之前对上下文执行ObjectStateManager魔术


还有别的办法吗

我建议在xaml中使用DataSource对象,并将列表视图的数据源设置为绑定到DataSource对象。也可以使用寻呼机,您可以从这里获得:http://cid-51b2fdd068799d15.office.live.com/self.aspx/.Public/Samples%5E_2010/20100929%5E_DataPagerForWPF.zip 其数据源也将绑定到数据源对象。这将实现两件事:

寻呼机将查询数据源对象,确保它一次只加载x个数据元素实体。但是,不要被愚弄,如果您有5000000个实体,那么您的数据上下文最终将在用户转到最后一页后将所有这些实体存储在内存中。这些实体确实会被垃圾收集

数据源对象包含上下文的全局实例,在控件或窗口被销毁和垃圾回收之前,该实例永远不会超出范围

这里有两条小贴士可以让你的生活更轻松:

默认情况下,实体实现INotifyPropertyChanged

我确实相信,只要上下文与被修改的实体存在于同一内存空间中,您所需要做的就是在上下文上调用SaveChanges,将更改提交给所有被修改的实体。您不必拆离实体,以便可以显示它们、修改它们以及用户修改它们,然后将实体重新附加到上下文,最后通知上下文实体已更改


使用更改跟踪POCO实体是您的一种选择吗


我忘了提到它是WinFormSal,所以我从我之前的问题中得到的印象是,将它从上下文中分离出来,不保持它一直运行是更好的。不,不是真的。上下文跟踪每个实体在其相应实体容器中发生的更改。分离时,必须显式调用:`context.ObjectStateManager.GetObjectStateEntry[object].SetModifiedProperty[property name];通知上下文,实体已随着您自己的发现而更改。我正在执行此操作。但我正在寻找一种方法,在上下文实际可用时推迟对上下文的调用,因为当它可用时,我实际上必须保存实体,或者在用户做任何事情时一直将其拖到上面。正如我前面所说,只要将网格或列表视图的数据源设置为上下文的实体容器,上下文就会自动跟踪用户修改的实体的更改,只要实体和编辑控件之间存在双向绑定。你不必拖任何东西过去。。。实体与其原始状态和修改状态一起缓存在上下文的实体容器中。您只需调用SaveChanges一次,即可一次性更新所有修改的实体。SaveChanges调用是在您的one-n-only save按钮的事件处理程序中完成的。我在查看自跟踪实体,但有人说它可能会砸到我的脸。如果我在使用实体框架从sql加载内容后分离上下文,您的解决方案会起作用吗?我使用了RIA服务上的自跟踪POCO,这有点不同,但在服务器端,当POCO从客户端返回时,它们没有连接,您可以重新连接POCO,然后评估映射的更改,并决定要保留或不保留哪些更改我正在做的是加载实体对象,分离上下文。。对对象执行一些操作,附加上下文并保存。欺骗
考虑到我怀疑它是否会起作用->如果我不去跟踪上下文并使用DetectChanges,那么可能,但在我看来,我将不得不手动更新属性,这就是我现在正在做的事情,但我遇到的问题是,我想在以后将这些更改通知上下文。延迟通知。。。我想不出任何干净的东西,如果你保留一份原始POCO的深度副本,你可以随时检查差异,但在我看来,这是非常丑陋的