【问题标题】:Reusing DbContext in Generic Repository在通用存储库中重用 DbContext
【发布时间】:2013-02-14 14:34:24
【问题描述】:

我正在使用 Entity Framework 5.0 实现存储库模式 - 至少我认为我是 :)。这就是我正在使用的

public abstract class GenericRepository<C, T> :
 IGenericRepository<T>
    where T : class
    where C : DbContext, new()
{
    private bool disposed = false;
    private C _entities = new C();
    protected C Context
    {
        get { return _entities; }
        set { _entities = value; }
    }

    public virtual IQueryable<T> GetAll()
    {
        IQueryable<T> query = _entities.Set<T>();
        return query;
    }

    public IQueryable<T> FindBy(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
    {
        IQueryable<T> query = _entities.Set<T>().Where(predicate);
        return query;
    }

    public virtual void Add(T entity)
    {
        _entities.Set<T>().Add(entity);
    }

    public virtual void Delete(T entity)
    {
        _entities.Set<T>().Remove(entity);
    }

    public virtual void Edit(T entity)
    {
        _entities.Entry(entity).State = System.Data.EntityState.Modified;
    }

    public virtual bool Save()
    {
        return (_entities.SaveChanges() > 0);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed)
            if (disposing)
                _entities.Dispose();

        this.disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

之后这个类被特定的存储库类继承 - 比如说 PlaceRepository

public class PlaceRepository : GenericRepository<DbEntities, Place>, IPlaceRepository
{ }

在另一层(业务层)中,我正在创建 PlaceRepository 类的实例 - 在名为 PlaceController 的类中。此类具有 PlaceEntity (CRUD) 的特定方法。在这个 PlaceController 中,我有一种方法用于在数据库中插入 Place 实体,但同时我在另一个表中插入一些东西(比如说 Country 表)。对于 Country 表上的 CRUD 操作,我有另一个名为 CountryRepository 的存储库。

综上所述,我在 Place Controller 中的方法创建了两个不同存储库的实例,以使用它们的方法,从而创建了两个不同的 DbContext 上下文。见下面的代码

public class PlaceController 
{ 
   public bool InsertPlace(Place toInsert)
   {
      PlaceRepository _placeRepo = new PlaceRepository();
      _placeRepo.Add(toInsert);

      Country _country = new Country();

      _country.Name = "default";

      CountryRepository _countryRepo = new CountryRepository();

      _countryRepo.Add(_country);

     //now i must call save on bothRepositories
     _countryRepo.Save(); _placeRepo.Save();

}
}

我需要对这种情况提出意见。创建上下文类的 2 个实例以进行两次插入是否很好?如果不是,我应该考虑使用/实现另一种模式吗?

【问题讨论】:

    标签: c# generics frameworks repository entity


    【解决方案1】:

    您应该为此使用 IoC(DI) 容器。这将帮助您在整个项目中使用 1 个上下文实例。您也可以查看 serviceLocator 模式的方式,但我建议使用 IoC(DI) 容器。我喜欢Castle.Windsor(DI模式的实现)你也可以看看Ninject。

    【讨论】:

    • (1) 这是否意味着我的业务层类必须使用上下文实例注入存储库(比如说构造函数注入)。然后我应该将上下文转发到通用存储库(没有 Ninject 等)(2)另一个问题。如果我的最顶层是 WCF 并且我有严格的引用,例如 WCF -> BusinessLayer -> DataLayer。我无法在 WCF 中创建上下文实例以将其传递给业务层。这是否意味着我不能在一个注入上下文中使用两个或多个业务层控制器?
    • 这一切都取决于实现。但我希望你应该:
    • 这一切都取决于实现。但我希望:(1)这是你的选择。但是 Castle.Windsor 可以用他所在的类独立地替换任何公共财产。在您的新闻层中,您只需调用: var service = Infrastructure.Container.Resolve();他将用已知类型替换所有链类公共属性。 (2)您可以根据需要使用尽可能多的不同业务层。 )
    • 如果你对这个话题感兴趣可以直接给我写信,我会尽力帮助的。很难用几句话来解释关系注入。
    • 我忘记了 - PlaceRepository _placeRepo = new PlaceRepository();应该是 PlaceController 的公共属性,所以它也会被注入 DI 容器。 ;) 这样您就可以根据需要获得任意数量的业务层。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-24
    • 1970-01-01
    • 2012-02-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多