【发布时间】:2013-12-03 00:38:33
【问题描述】:
或我们的一个项目(C# Windows 服务,主要用于处理来自外部资源的数据并将这些数据读/写到 SQL Server 数据库)我们已经在 DAL 中实现了存储库模式,并且我们为每个 POCO 对象(代表一个表格行)。这些存储库类的使用由工作单元模式管理,因此所有存储库在单个工作单元内共享相同的 DbContext,但这可能与问题无关。
假设一个客户实体的存储库类实现如下:
public class CustomerRepository
{
private readonly MyContext _context;
public CustomerRepository(MyContext context)
{
_context = context;
}
public Customer GetCustomer(string id)
{
return _context.Customers.Find(new object[] {id});
}
public IEnumerable<Customer> GetAllCustomers(Func<Customer,bool> predicate )
{
return _context.Customers.Where(predicate);
}
public IEnumerable<Customer> GetCustomerByCity(string city)
{
return _context.Customers.Where(c=>s.City.Equals(city));
}
public void SetAge(string id, byte age)
{
_context.Customers.Find(new object[] { id }).Age = age;
}
public void Update(Customer customer)
{
_context.Entry(customer).State = EntityState.Modified;
}
}
现在我有几个关于更新方法的最佳实践的问题:
- 是否建议使用单独的方法来更新数据库中的特定字段,例如 SetAge() 方法?
- 或者是否建议将 Customer 对象获取到我们的 BLL(使用 GetCustomer(id)),然后在 BLL 中设置属性,如 customer.Age = 35;,然后保存此更改?
更新操作大多限于单行中的单个字段。
也许有人愿意和我分享一些现实世界的想法?
【问题讨论】:
-
如果您考虑对所有属性进行特定更新操作的实用性,那么答案是相当明显的。此外,考虑到您将多次访问数据库以更新同一个对象,这种方法可能不会很好地扩展。
-
@James 更新操作大多限于单行中的单个字段,因此这里有多个往返不是问题。就相关而言,实体框架会跟踪更改(更改保留在内存中),并且当在我们的上下文对象上调用 SaveChanges 时,记录将一次性提交到数据库。
-
对我来说很好,
SetAge是域逻辑,因此并不真正属于存储库层。如果你问做你正在做的事情是否有任何伤害,那么答案是否定的。但是,请考虑诸如编辑实体的影响之类的事情,即删除/重命名属性或添加新属性。您实际上所做的只是给自己不必要的额外工作,EF 足够聪明,只会更新已更改的内容。 -
顺便说一句,我预测您的存档有问题。引用msdn.microsoft.com/en-us/library/…:“DbContext 实例代表工作单元和存储库模式的组合”。 IDbSets 是存储库,SaveChanges 应该是工作单元的责任。我建议你将该方法移到工作单元类中
-
@Colin 你说的很对。 save 方法实际上是我的工作单元的一部分。从我的项目中复制粘贴时必须在这个例子中偷偷摸摸...谢谢
标签: c# entity-framework repository-pattern data-access-layer