예 저장소를 사용하고 있어도 상황을 처리해야합니다. ObjectContext를 여전히 생성자의 매개 변수로 제공하고 있기 때문에 Repository 구현에서 제공하는 이점이 명확하지 않은가요?
IMO 저장소 및 사용자 지정 UnitOfWork를 사용하는 주된 이유는 ObjectContext + ObjectSet 자체가 저장소 및 작업 단위 패턴의 구현이기 때문에 상위 응용 프로그램 계층에서 persistance ignorance = hidding EF 코드입니다.
저장소를 사용할 경우 항상 전체 EF 코드를 래핑하므로 저장소의 공용 인터페이스는 EF 관련 인프라에 대한 정보를 제공하지 않습니다. 이 경우 ObjectContext를 다루는 방법은 나에게 달려있다.
간단한 직선 CRUD 시나리오를 위해 컨텍스트 생성을 마무리하고 각 저장소 방법으로 처리 할 수 있습니다. 더 복잡한 시나리오에서는 컨텍스트 생성 및 폐기를 래핑하고 데이터베이스에 변경 내용을 저장하는 추가 클래스 인 UnitOfWork (UoW)를 사용하고 있습니다. 또한 모든 저장소의 팩토리 역할을하고 작성된 컨텍스트의 인스턴스를 저장소의 생성자로 전달합니다.
대부분의 경우 서비스 또는 웹 응용 프로그램을 프로그래밍하므로 분리 된 객체를 처리하고 있습니다. 나는 항상 요청 처리를 위해 단일 UoW 인스턴스를 사용하고있다. 따라서 UoW는 요청 처리 시작시 작성되고 요청 처리가 끝나면 해제됩니다. WinForms/WPF 응용 프로그램 및 첨부 된 개체의 경우 좋은 생각은 "폼 당"UoW/ObjectContext 인스턴스를 갖는 것입니다 - MSDN 매거진에서 NHibernate 세션 (EF ObjectContext와 동일)을 사용하여이 방법을 설명하는 article이 있습니다.
의 UnitOfWork 및 저장소 패턴의 일부 시작 구현 : 저장소에 대한
컨텍스트 홀더와 추상적 인 공장 분리 된 실체
에 대한
public interface IUnitOfWork
{
IRepository<MyEntity> MyEntityRepository { get; }
// Repositories for other entities
SaveChanges();
}
저장소
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);
}
의 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;
}
}
}
}
자료 저장소 구현
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);
}
}
사용 데이터
using (var uow = new UnitOfWork(connectionString))
{
uow.MyEntitiesRepository.Update(entity);
uow.SaveChanges();
}
Fantastic.Thanks을 modifing에 때 데이터
사용 을 선택! 이 리포지토리에서 내가 가진 유일한 문제는 그들 중 누구도 "Include"Eager 로딩을 처리하지 않는다는 것입니다. 저장소로 어떻게 열망합니까? – user9969
Include는 EF ObjectQuery의 기능이기 때문에 까다로운 부분입니다. 저는 일반적으로 GeneralRepository에서 상속받은 저장소를 만들고 필요한 Include를 재정의 된 GetQuery에 추가합니다. 그러나 일부 쿼리에 대해서만 열기를 활성화해야하는 경우 도움이되지 않습니다. 이 경우에는 다른 것을 필요로합니다. Linq-To-SQL에서 LoadOptions를 구현하고이 옵션을 UnitOfWork 또는 Repository에 전달하는 것과 같은 것을 상상할 수 있습니다. 그런 다음 optins를 사용하여 모두 포함을 설정합니다. –
아주 깊이있는 대답 - 그러나, UnitOfWork 클래스는 하나의 로컬 스코프 된 IRepository 인스턴스를 가지고 있습니다. 이것은 작업 단위가 작업 할 저장소를 정의하고 있음을 의미합니다. 이것은 정확하지 않습니다. 작업 단위 (Unit of Work)의 요점은 여러 저장소에서 트랜잭션을 처리하는 것입니다 (일반적으로 UoW는 해당 저장소를 통해 1- * 저장소를 허용합니다). 이 구현은 전혀 처리하지 않습니다. 어쩌면 이것은 OP에게는 좋을지도 모릅니다. – RPM1984