2011-01-25 73 views
1

我試圖設置一個使用UnitOfWork和Repository模式的項目。爲什麼我的DataContext沒有看到對對象(Unit Of Work)的更改?

現在我不能使用一個IoC和EF4,所以我想用Linq和DataContext的一點依賴性:(。我不會隱瞞我對所有的集成有點困惑這些概念我注意到調試我的代碼,DataContext沒有看到對某個對象所做的更新,但是每次都向數據庫添加一個新的實體。我的問題,也許這是一個簡單的步驟。在我繼續之前,這裏是我的:

例如,我有一個對象叫foo ...我有foo控制器,在構造函數中創建fooRepository的一個新實例。 fooRepository我添加了一個對我的UnitOfWork的引用包裝DataContext ...是嗎? 這裏是我的代碼

public class ListaController : Controller 
{ 

    IListaRepository _listaRepository;  

    public ListaController() 
     : this(new ListaRepository()) { 
    } 

    public ListaController(IListaRepository repository) 
    { 
     _listaRepository = repository; 
    } 

    [HttpPost] 
    public ActionResult Edit(int id, Lista lista) 
    { 
     try 
     { 
      this._listaRepository.Save(lista); 
      return RedirectToAction("Index"); 

     } 
     catch 
     { 
      return View(); 
     } 
    } 
} 

    public class ListaRepository : LinqRepository<Lista>, IListaRepository 
    { 

    protected IUnitOfWork uow 
    { 
     get { return base.GetCurrentUnitOfWork<IUnitOfWork>(); } 
    } 

    public ListaRepository() 
     : base() 
    { 
    } 

    public override void Add(Lista lista) 
    { 
     this.uow.Context.Listas.InsertOnSubmit(lista); 
     this.uow.Commit(); 
    } 

    public override void Save(Lista lista) 
    { 
     Add(lista); 
    } 
    } 

    public static class UnitOfWork 
    { 
    private const string HTTPCONTEXTKEY = "Domain.HttpContext.Key"; 

    private static IUnitOfWorkFactory _unitOfWorkFactory; 
    private static readonly Hashtable _threads = new Hashtable(); 

    public static void Commit() 
    { 
     IUnitOfWork unitOfWork = GetUnitOfWork(); 
     if (unitOfWork != null) 
     { 
      unitOfWork.Commit(); 
     } 
    } 

    public static IUnitOfWork Current 
    { 
     get 
     { 
      IUnitOfWork unitOfWork = GetUnitOfWork(); 
      if (unitOfWork == null) 
      { 
       //Qui inserisco dipendenza in quanto non uso un IoC 
       //_unitOfWorkFactory = ObjectFactory.GetInstance<IUnitOfWorkFactory>(); 
       _unitOfWorkFactory = new LinqUnitOfWorkFactory(); 
       unitOfWork = _unitOfWorkFactory.Create(); 
       SaveUnitOfWork(unitOfWork); 
      } 
      return unitOfWork; 
     } 
    } 

    private static IUnitOfWork GetUnitOfWork() 
    { 
     if (HttpContext.Current != null) 
     { 
      if (HttpContext.Current.Items.Contains(HTTPCONTEXTKEY)) 
      { 
       return (IUnitOfWork)HttpContext.Current.Items[HTTPCONTEXTKEY]; 
      } 
      return null; 
     } 
     else 
     { 
      Thread thread = Thread.CurrentThread; 
      if (string.IsNullOrEmpty(thread.Name)) 
      { 
       thread.Name = Guid.NewGuid().ToString(); 
       return null; 
      } 
      else 
      { 
       lock (_threads.SyncRoot) 
       { 
        return (IUnitOfWork)_threads[Thread.CurrentThread.Name]; 
       } 
      } 
     } 
    } 

    private static void SaveUnitOfWork(IUnitOfWork unitOfWork) 
    { 
     if (HttpContext.Current != null) 
     { 
      HttpContext.Current.Items[HTTPCONTEXTKEY] = unitOfWork; 
     } 
     else 
     { 
      lock (_threads.SyncRoot) 
      { 
       _threads[Thread.CurrentThread.Name] = unitOfWork; 
      } 
     } 
    } 
    } 

public abstract class LinqRepository<T> : IRepository<T> where T : class 
{ 
    protected ManagerEmailDataContext _context = new ManagerEmailDataContext(); 

    protected ManagerEmailDataContext Context 
    { 
     get 
     { 
      if (_context == null) 
      { 
       _context = GetCurrentUnitOfWork<LinqUnitOfWork>().Context; 
      } 
      return _context; 
     } 
    } 

    public TUnitOfWork GetCurrentUnitOfWork<TUnitOfWork>() where TUnitOfWork : IUnitOfWork 
    { 
     return (TUnitOfWork)UnitOfWork.Current; 
    } 


    public abstract IQueryable<T> GetAll(); 
    public abstract void Add(T entity); 
    public abstract void Save(T entity); 
    public abstract T Get(int id); 
} 

protected void Application_Start() 
{ 
    AreaRegistration.RegisterAllAreas(); 
    RegisterGlobalFilters(GlobalFilters.Filters); 
    RegisterRoutes(RouteTable.Routes); 
    LinqUnitOfWorkFactory.SetDataContext(() => new ManagerEmailDataContext()); 
} 

public class LinqUnitOfWorkFactory : ManagerEmail.Models.IUnitOfWorkFactory 
{ 
    private static Func<ManagerEmailDataContext> _objectContextDelegate; 
    private static readonly Object _lockObject = new object(); 

    public static void SetDataContext(Func<ManagerEmailDataContext> objectDataContextDelegate) 
    { 
     _objectContextDelegate = objectDataContextDelegate; 
    } 

    public IUnitOfWork Create() 
    { 
     ManagerEmailDataContext context; 
     lock (_lockObject) 
     { 
      context = _objectContextDelegate(); 
     } 
     return new LinqUnitOfWork(context); 
    } 
}`enter code here` 

任何幫助或建議將不勝感激!

對不起,如果我發佈了所有的代碼,但這是一個令我瘋狂的事情。

回答

0

該問題與LINQ有關。在我的控制器我調用Save(T實體)方法,並在我的倉庫我有

public override void Save(Lista lista) 
{ 
    Lista original = CloneEntity<Lista>(this.Get(lista.Id)); 
    this._uow = new LinqUnitOfWorkFactory().Create(); //I must renew the DataContext 
    this._uow.Context.Listas.Attach(lista, original); 
    this._uow.Context.Refresh(RefreshMode.KeepChanges, lista); 
    this._uow.Commit(); 
} 

internal static T CloneEntity<T>(T originalEntity) 
{ 
    Type entityType = typeof(T); 
    DataContractSerializer ser = new DataContractSerializer(entityType); 
    using (MemoryStream ms = new MemoryStream()) 
    { 
     ser.WriteObject(ms, originalEntity); 
     ms.Position = 0; 
     return (T)ser.ReadObject(ms); 
    } 
} 

希望這可以幫助別人。

0

我看不到您要撥打的電話DataContext.SubmitChanges()。您的工作單元Commit()方法需要在某個時刻調用它以將更改保存到數據庫。

+0

是的,我的mystake。我沒有在我的UnitOfWork(我稱之爲SubmitChanges())中發佈Commit方法,但問題與不同的數據上下文有關。我用上面的代碼解決了。謝謝! – stuzzo 2011-01-28 09:20:15

相關問題