use*_*969 31 repository-pattern entity-framework-4
EF的新手,我注意到使用存储库模式可以真正简化事情并允许我做一些嘲弄.太好了.
我的问题
objectContext的典型用法是尽快销毁,见下文
using (var context = new SchoolEntities())
{
context.AddToDepartments(department);
context.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)
使用Repository模式我注意到没有人真正使用"使用模式",例如
using (var repository= new Repository<Student>(new MyContext))
{
repository.Add(myStudentEntity)
repository.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)
应该是我们应该尽快处理上下文,否则内存可能会泄漏或变得非常大?
任何人都可以澄清吗?非常感谢.
Lad*_*nka 50
是的,即使您使用存储库,也应该处置上下文.目前尚不清楚您的Repository实现给您带来了什么好处,因为您仍然提供ObjectContext作为构造函数的参数,不是吗?
IMO使用Repository和自定义UnitOfWork的主要原因是持久性无知=隐藏来自上层应用程序层的EF代码,因为ObjectContext + ObjectSet本身是存储库和工作单元模块的实现.
如果我正在使用存储库,我总是包装整个EF代码,因此我的存储库的公共接口不提供有关EF相关基础结构的任何信息.在这种情况下,我应该如何处理ObjectContext.
对于简单直接的CRUD场景,我可以将上下文创建和处理包装到每个存储库方法中.在更复杂的场景中,我正在使用其他类 - UnitOfWork(UoW),它包装上下文创建和处理,并触发将更改保存到数据库中.它还充当所有存储库的工厂,并将创建的上下文的实例传递到存储库的构造函数.
大多数时候我正在编程服务或Web应用程序,所以我正在处理分离的对象.我总是使用单个UoW实例进行请求处理.因此,UoW在请求处理开始时创建,并在请求处理结束时释放.在WinForms/WPF应用程序和附加对象的情况下,我认为好的想法是"每个表单"都有UoW/ObjectContext实例 - 有一篇文章用MSDN杂志中的NHibernate会话(与EF ObjectContext相同)描述了这种方法.
一些单元开始实现UnitOfWork和Repository模式:
上下文持有者和存储库的抽象工厂
public interface IUnitOfWork
{
IRepository<MyEntity> MyEntityRepository { get; }
// Repositories for other entities
SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)
分离实体的存储库
public interface IRepository<T> where T : class
{
IQueryable<T> GetQuery();
void Insert(T entity);
void Delete(T entity);
// In very complex scenarios with big object graphs you will probably give up
// using detached approach and you will always load your entities from DB before
// deleting or updating them. In such case you will not need Update method at all.
void Update(T entity);
}
Run Code Online (Sandbox Code Playgroud)
UnitOfWork包装Enitity框架的一次性实现
public class UnitOfWork : IUnitOfWork, IDisposable
{
private ObjectContext _context = null;
public UnitOfWork(string connectionString)
{
if (String.IsNullOrEmpty(connectionString)) throw new ArgumentNullException("connectionString");
_context = new ObjectContext(connectionString);
}
private IRepository<MyEntity> _myEntityRepository;
public IRepository<MyEntity> MyEntityRepository
{
get
{
return _myEntityRepository ?? (_myEntityRepository = new GeneralRepository<MyEntity>(_context));
}
}
public void SaveChanges()
{
_context.SaveChanges();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (_context != null)
{
_context.Dispose();
_context = null;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
基础存储库实现
public class GeneralRepository<T> : IRepository<T> where T : class
{
private ObjectSet<T> _set;
private ObjectContext _context;
public GeneralRepository(ObjectContext context)
{
if (context == null) throw new ArgumentNullException("context");
_context = context;
_set = context.CreateObjectSet<T>();
}
// Override this method for example if you need Includes
public virtual IQueryable<T> GetQuery()
{
return _set;
}
// Override following methods if you are working with object graphs.
// Methods do not execute operations in database. It is responsibility of
// UnitOfWork to trigger the execution
public virtual void Insert(T entity)
{
if (entity == null) throw new ArgumentNullException("entity");
_set.AddObject(entity);
}
// These impelementations are for detached scenarios like web application
public virtual void Delete(T entity)
{
if (entity == null) throw new ArgumentNullException("entity");
_set.Attach(entity);
_set.DeleteObject(entity);
}
public virtual void Update(T entity)
{
if (entity == null) throw new ArgumentNullException("entity");
_set.Attach(entity);
_context.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified);
}
}
Run Code Online (Sandbox Code Playgroud)
选择数据时的用法
using (var uow = new UnitOfWork(connectionString))
{
var entity = uow.MyEntitiesRepository.GetQuery().Single(e => e.Id == 1);
// Do something with entity
}
Run Code Online (Sandbox Code Playgroud)
修改数据时的用法
using (var uow = new UnitOfWork(connectionString))
{
uow.MyEntitiesRepository.Update(entity);
uow.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13610 次 |
| 最近记录: |