Ответ 1
DataContext или ObjectContext - это единица работы.
Таким образом, ваш DAL будет сохранять, удалять и извлекать объекты, а ваш DataContext/ObjectContext будет отслеживать ваши объекты, управлять транзакциями и применять изменения.
Это пример , чтобы проиллюстрировать идею решения.
using(var context = new ObjectContext()) { // Unit of Work
var repo = new ProductRepository(context);
var product = repo.GetXXXXXXX(...);
...
// Do whatever tracking you want to do with the object context. For instance:
// if( error == false) {
// context.DetectChanges();
// context.SaveChanges(SaveOptions.AcceptAllChangesAfterSave);
// }
}
И ваш репозиторий будет выглядеть так:
public abstract class Repository {
public Respository(ObjectContext context){
CurrentContext = context;
}
protected ObjectContext CurrentContext { get; private set; }
}
public class ProductRespository : Repository {
public ProductRespository(ObjectContext context) : base(context){
}
public Product GetXXXXXX(...){
return CurrentContext... ; //Do something with the context
}
}
Другой способ - поместить единицу работы (контекст объекта) глобально:
Вам нужно определить, какова будет ваша единица работы. В этом примере это будет веб-запрос. В реализации реального мира я бы использовал для этого инъекцию зависимостей.
public static class ContextProvider {
public static ObjectContext CurrentContext {
get { return HttpContext.Items["CurrentObjectContext"];
}
public static void OpenNew(){
var context = new ObjectContext();
HttpContext.Items["CurrentObjectContext"] = context;
}
public static void CloseCurrent(){
var context = CurrentContext;
HttpContext.Items["CurrentObjectContext"] = null;
// Do whatever tracking you want to do with the object context. For instance:
// if( error == false) {
// context.DetectChanges();
// context.SaveChanges(SaveOptions.AcceptAllChangesAfterSave);
// }
context.Dispose();
}
}
В этом примере ObjectContext является единицей работы и будет жить в текущем запросе. В своем глобальном asax вы можете добавить:
protected void Application_BeginRequest(object sender, EventArgs e){
ContextProvider.OpenNew();
}
protected void Application_EndRequest(object sender, EventArgs e){
ContextProvider.CloseCurrent();
}
В ваших репозиториях вы просто вызываете ContextProvider.CurrentContext