我有一个简单的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();
}
}
这可行..但我想做的事实上并不是在用户更改之后立即保存更改,但最后当他按下BIG按钮SAVE ALL
时,它会通过所有ObjectListView项目和根据需要在数据库中更新它们。问题是我无法更新上下文并在以后执行它,因为Context不会被使用,但最终会在保存所有内容时使用。
那么我的选择是什么?我被指向使用INotifyPropertyChanged但是,尽管我看了代码,但我认为它不适合这种情况,或者我根本不知道如何使用它。
另一种选择是实际从数据库中为每个Column
创建bool值,如
public partial class Person
{
public bool NameChanged {get;set; }
public bool SurnameChanged { get; set; }
}
保存时我将检查bool是否更改,如果是,则在保存之前对上下文执行ObjectStateManager魔术。
还有其他办法吗?
答案 0 :(得分:0)
我建议在xaml中使用DataSource对象,并将列表视图的数据源设置为绑定到DataSource对象。还可以使用寻呼机(你可以从这里得到一个:http://cid-51b2fdd068799d15.office.live.com/self.aspx/.Public/Samples%5E_2010/20100929%5E_DataPagerForWPF.zip)其数据源也将是绑定到DataSource对象。这将实现两件事:
寻呼机将查询数据源对象,确保一次只加载x个数据元素(实体)。但是,如果您有5000000个实体,则不要被愚弄,您的数据上下文最终会在用户转到最后一页后将所有这些实体存储在内存中。这些实体确实收集了垃圾。
数据源对象包含上下文的全局实例,在控件或窗口被销毁并进行垃圾回收之前,该实例永远不会超出范围。
这里说的是让你的生活更轻松的两个秘诀:
默认情况下,实体实现INotifyPropertyChanged。
我相信只要上下文存在于与被修改的实体相同的内存空间中,您需要做的就是在上下文中调用SaveChanges()以将更改提交给所有已修改的实体。您不必拆除实体,以便您可以显示它们,修改它们(用户修改它们),然后将实体重新附加到上下文,最后通知上下文实体已更改。
答案 1 :(得分:0)
使用更改跟踪POCO实体是您的选择吗?