直接使用上下文是一个好主意吗?例如,假设我有一个客户数据库,用户可以按名称搜索他们,显示一个列表,选择一个,然后编辑该客户的属性。
看来我应该使用上下文来获取客户列表(映射到 POCO 或CustomerViewModels
),然后立即关闭上下文。然后,当用户选择CustomerViewModels
列表中的一个时,UI 的客户属性部分将填充。
接下来,他们可以更改名称、类型、网站地址、公司规模等。点击保存按钮后,我打开一个新上下文,使用 IDCustomerViewModel
检索该客户记录,并更新其每个属性。最后,我调用SaveChanges()
并关闭上下文。这是很多工作。
我的问题是为什么不直接使用上下文使其始终保持打开状态?我读过使用具有长生命周期范围的相同上下文非常糟糕,并且不可避免地会导致问题。我的假设是,如果该应用程序只能由一个人使用,我可以让上下文保持打开状态并做所有事情。但是,如果有很多用户,我想维护一个简洁的工作单元,从而根据每个请求打开和关闭上下文。
有什么建议么?谢谢。
@PGallagher - 感谢您的彻底回答。
@Brice - 您的意见也很有帮助
但是,@Manos D.“冗余代码的缩影”评论让我有点担心。让我通过一个例子。假设我将客户存储在数据库中,而我的客户属性之一是 CommunicationMethod。
[Flags]
public enum CommunicationMethod
{
None = 0,
Print = 1,
Email = 2,
Fax = 4
}
WPF 中我的管理客户页面的 UI 将在客户通信方式(打印、电子邮件、传真)下包含三个复选框。我无法将每个复选框绑定到该枚举,这没有意义。另外,如果用户点击了那个客户,起床去吃午饭怎么办……上下文在那里呆了几个小时,这很糟糕。相反,这是我的思考过程。
最终用户从列表中选择一个客户。我新建了一个上下文,找到该客户并返回一个 CustomerViewModel,然后关闭该上下文(为简单起见,我在这里留下了存储库)。
using(MyContext ctx = new MyContext())
{
CurrentCustomerVM = new CustomerViewModel(ctx.Customers.Find(customerId));
}
现在用户可以选中/取消选中 Print、Email、Fax 按钮,因为它们绑定到 CustomerViewModel 中的三个 bool 属性,它也有一个 Save() 方法。开始。
public class CustomerViewModel : ViewModelBase
{
Customer _customer;
public CustomerViewModel(Customer customer)
{
_customer = customer;
}
public bool CommunicateViaEmail
{
get { return _customer.CommunicationMethod.HasFlag(CommunicationMethod.Email); }
set
{
if (value == _customer.CommunicationMethod.HasFlag(CommunicationMethod.Email)) return;
if (value)
_customer.CommunicationMethod |= CommunicationMethod.Email;
else
_customer.CommunicationMethod &= ~CommunicationMethod.Email;
}
}
public bool CommunicateViaFax
{
get { return _customer.CommunicationMethod.HasFlag(CommunicationMethod.Fax); }
set
{
if (value == _customer.CommunicationMethod.HasFlag(CommunicationMethod.Fax)) return;
if (value)
_customer.CommunicationMethod |= CommunicationMethod.Fax;
else
_customer.CommunicationMethod &= ~CommunicationMethod.Fax;
}
}
public bool CommunicateViaPrint
{
get { return _customer.CommunicateViaPrint.HasFlag(CommunicationMethod.Print); }
set
{
if (value == _customer.CommunicateViaPrint.HasFlag(CommunicationMethod.Print)) return;
if (value)
_customer.CommunicateViaPrint |= CommunicationMethod.Print;
else
_customer.CommunicateViaPrint &= ~CommunicationMethod.Print;
}
}
public void Save()
{
using (MyContext ctx = new MyContext())
{
var toUpdate = ctx.Customers.Find(_customer.Id);
toUpdate.CommunicateViaEmail = _customer.CommunicateViaEmail;
toUpdate.CommunicateViaFax = _customer.CommunicateViaFax;
toUpdate.CommunicateViaPrint = _customer.CommunicateViaPrint;
ctx.SaveChanges();
}
}
}
你觉得这有什么问题吗?