0

希望有人可以指出如何做到这一点:

我有一个使用实体框架的 WinForms 应用程序。例如,我们通过提供 BindingList 的存储库将数据绑定到 gridControl。

例如(简化代码)

class ProductRepository {
   public void LoadAll() {
           _context.Products.Where(p => p.Deleted == false).Load();
   }

   public BindingList<T> GetBindingList() {
           LoadAll();
           return _context.Products.Local.ToBindingList();
   }
}

class ProductListPresenter {
    private void SetList() {
       _view.SetList(productRepo.GetBindingList());
    }
}

class ProductListView {
     DeletedButton.Click += {
         (bindingSource1.Current as Product).Deleted = 1;
         gridControl1.Refresh();
     };
}

但是:我只想显示未删除的产品(Product.Deleted == false)。可以在 Repository Load() 方法中过滤它,但是当我已经将它绑定到我的控件时如何过滤它?我不能做 bindingSource1.RemoveCurrent() 因为它会完全擦除实体并将其标记为 State.Deleted..

这里要考虑的另一件事是:我还有其他一些事情正在以这种形式进行,只有当用户决定通过单击“保存”按钮来保存更改时,我才需要在数据库中提交的所有更改。在用户明确保存更改之前,我必须使用内存状态。

有什么建议么?在 WinForms 中使用 EF 不知何故开始提高挫败感。

4

1 回答 1

0

因为您是在逻辑上而不是在物理上删除,所以您需要将删除事件冒泡到有权访问存储库或上下文的层,然后保存更改,然后从上下文中分离实体。例子:

class ProductListPresenter {

    private void DeleteHandler(Object sender, EventArgs e)
    {
       productRepo.SaveChanges();
       productRepo.DetachLogicallyDeletedEntities();
    }
}

class ProductRepository 
{
  public void DetachLogicallyDeletedEntities()
  {
   foreach(var entity in _context.Products.Local
           .Where(p=>p.Deleted == 1).ToList())
               _context.Entry(entity).State = EntityState.Detached;
   }
}

如果这是不可取的,那么另一个选项是不绑定到上下文本地集合,而是绑定到一个独立的集合BindingList<>,然后您可以直接在视图层中将其从列表中删除。

class ProductListView {
     DeletedButton.Click += {
         (bindingSource1.Current as Product).Deleted = 1;
         bindingSource1.Remove(bindingSource1.Current);
     };
}

第三种方法是创建一个IBindingListView在本地保存和缓存上下文的实现,并ObservableCollection<>在本地集合保存的内容与提供的显示内容之间提供一层间接性。这样您就可以使用该BindingSource.Filter属性来提供过滤器字符串。

于 2013-07-31T10:14:35.987 回答