Entity Framework,使用 dispose 方法的 UnitofWork 模式
Entity Framework, UnitofWork pattern with dispose method
uow 样本:
using System;
using ContosoUniversity.Models;
namespace ContosoUniversity.DAL
{
public class UnitOfWork : IDisposable
{
private SchoolContext context = new SchoolContext();
private GenericRepository<Department> departmentRepository;
private GenericRepository<Course> courseRepository;
public GenericRepository<Department> DepartmentRepository
{
get
{
if (this.departmentRepository == null)
{
this.departmentRepository = new GenericRepository<Department>(context);
}
return departmentRepository;
}
}
public GenericRepository<Course> CourseRepository
{
get
{
if (this.courseRepository == null)
{
this.courseRepository = new GenericRepository<Course>(context);
}
return courseRepository;
}
}
public void Save()
{
context.SaveChanges();
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
context.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
}
如您所见,uow 包含 dispose 方法并在其中处理 dbContex 对象。为什么我们要显式处理 dbContext 对象。由于它是 uow 的成员,在范围之外它将由垃圾收集器自动处理。那么,为什么我们要手动执行此操作?例如:
using(Uow uowObject = new Uow())
{
//there is a dbcontext
}
//it will be disposed automaticly by gc
在范围之外,变量不再可访问,但这并不意味着已处置。根据经验,每个实现 IDisposable 的 class 都应该被释放。对于 EF,它将清除缓存、跟踪对象更改的图形并回滚任何未提交的事务。
有了GC,你不知道GC什么时候开始。即使变量超出范围,也不意味着它已被垃圾回收。使用处理模式,您可以立即释放内存。
来自 MSDN :在确定何时安排垃圾收集时,运行时会考虑分配了多少托管内存。如果一个小的托管对象分配了大量的非托管内存,运行时只考虑托管内存,从而低估了调度垃圾回收的紧迫性。
所以对于持有原生资源的托管对象,应该调用dispose释放原生资源。
uow 样本:
using System;
using ContosoUniversity.Models;
namespace ContosoUniversity.DAL
{
public class UnitOfWork : IDisposable
{
private SchoolContext context = new SchoolContext();
private GenericRepository<Department> departmentRepository;
private GenericRepository<Course> courseRepository;
public GenericRepository<Department> DepartmentRepository
{
get
{
if (this.departmentRepository == null)
{
this.departmentRepository = new GenericRepository<Department>(context);
}
return departmentRepository;
}
}
public GenericRepository<Course> CourseRepository
{
get
{
if (this.courseRepository == null)
{
this.courseRepository = new GenericRepository<Course>(context);
}
return courseRepository;
}
}
public void Save()
{
context.SaveChanges();
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
context.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
}
如您所见,uow 包含 dispose 方法并在其中处理 dbContex 对象。为什么我们要显式处理 dbContext 对象。由于它是 uow 的成员,在范围之外它将由垃圾收集器自动处理。那么,为什么我们要手动执行此操作?例如:
using(Uow uowObject = new Uow())
{
//there is a dbcontext
}
//it will be disposed automaticly by gc
在范围之外,变量不再可访问,但这并不意味着已处置。根据经验,每个实现 IDisposable 的 class 都应该被释放。对于 EF,它将清除缓存、跟踪对象更改的图形并回滚任何未提交的事务。
有了GC,你不知道GC什么时候开始。即使变量超出范围,也不意味着它已被垃圾回收。使用处理模式,您可以立即释放内存。
来自 MSDN :在确定何时安排垃圾收集时,运行时会考虑分配了多少托管内存。如果一个小的托管对象分配了大量的非托管内存,运行时只考虑托管内存,从而低估了调度垃圾回收的紧迫性。
所以对于持有原生资源的托管对象,应该调用dispose释放原生资源。