稍后通知实体框架上下文有关更改,而不是在对象属性更改时通知

发布于 2025-01-06 20:17:44 字数 1756 浏览 3 评论 0原文

我有简单的 ObjectListView,它显示来自 EntityFramework 的名为 Person 的对象的一些列(为了简化事情)。我使用实体框架将其加载到ObjectListview,然后将其从上下文中deatch。该人有多个字段(如姓名、姓氏、文件……)。

考虑到某些文件有 5mb-50mb,我不想在不需要的情况下将它们加载/保存到数据库中。现在,当有人双击 ObjectListView 时,所选的 Person 就会加载到 TextBox 字段中。编辑任何字段时,我会检查 Person Name 或 SurName 是否更改,如果更改,我会更新上下文,如下面的代码所示。

    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();
        }

    }

这是可行的..但我想做的实际上并不是在用户更改后立即保存更改,而是最后当他按下大按钮 SAVE ALL 时,这样它就会遍历所有 ObjectListView 项目并根据需要在数据库中更新它们。问题是我无法更新上下文并稍后再执行,因为当时不会使用上下文,但最终会在保存所有内容时使用。

那么我有什么选择呢?我被指出使用 INotifyPropertyChanged但尽管我查看了代码,但我认为它不适合这种情况,或者我根本不知道如何使用它。

另一种选择是从数据库中为每个实际创建 bool 值

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

    public bool SurnameChanged { get; set; }
}

,在保存时我会检查 bool 是否发生变化,如果是,则在保存之前对上下文执行 ObjectStateManager 魔法。

还有其他方法可以做到这一点吗?

I have simple ObjectListView which displays some columns from EntityFramework of objects called Person (to simplify things). I load it with Entity Framework to ObjectListviewand then deatch it from Context. The person has multiple fields (like Name, Surname, File, ...).

Considering that some files are 5mb-50mb I don't want to load/save them to database without need. Now when someone double clicks in ObjectListView the selected Person is loaded into TextBox fields. When editing any of the fields I check if Person Name or SurName changed and if it did I updated the context like in the code below.

    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();
        }

    }

This works.. but what I would like to do is actually not save the changes straight away after users changes it but in the end when he presses BIG button SAVE ALL so then it would go thru all ObjectListView items and update them as needed in database. The problem is I can't update context and do it later since the Context wouldn't be used then but in the end when saving everything.

So what are my options? I was pointed to use INotifyPropertyChanged but as much as I looked at the code I don't think it's good for this type of situation or I simply don't know how to use it.

The other option was to actually create bool value per each Column from the database like

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

    public bool SurnameChanged { get; set; }
}

And when saving I would be checking if bool changed and if yes do the ObjectStateManager magic on the context prior to save.

Any other way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

瑕疵 2025-01-13 20:17:45

使用变更跟踪 POCO 实体是否适合您?

http://msdn.microsoft.com/en-us/library/dd456848.aspx

Is using change tracking POCO entities an option for you?

http://msdn.microsoft.com/en-us/library/dd456848.aspx

哎呦我呸! 2025-01-13 20:17:44

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

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

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

话虽如此,这里有两个技巧可以让您的生活更轻松:

  1. 实体默认实现 INotifyPropertyChanged。

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

I would advise to use a DataSource object in your xaml, and set your list view's data source to be bound to the DataSource object. Also use a pager, (You can get one from here:http://cid-51b2fdd068799d15.office.live.com/self.aspx/.Public/Samples%5E_2010/20100929%5E_DataPagerForWPF.zip) whose data source will also be bound to the DataSource object. That wold achieve 2 things:

  1. The pager will query the data source object ensuring that it loads only x number of data elements (entities) at a time. Do not, however be fooled that if you have 5000000 entities, your data context will eventually store all of these entities in memory after the user has gone to the last page. These entities do get garbage collected.

  2. The data source object contains a global instance of the context which will never go out of scope until the control or window is destroyed and garbage collected.

That being said here are two tips to make your life easier:

  1. Entities by default implement INotifyPropertyChanged.

  2. I do believe that as long as the context exists in the same memory space as the entities being modified, all you need to do is call SaveChanges() on the context to commit the changes to all modified entities. YOU DON'T HAVE TO DETACH the entities so that you can display them, modify them (well your user modifies them), then re-attach the entities to the context, and finally notify the context that the entity has changed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文