通用存储库设计

时间:2011-03-01 06:37:20

标签: .net entity-framework-4

您好我正在尝试在EF4上创建一个通用存储库。而不是去不同的存储库& UnitOfWork实现,我希望创建一个存储库类,它将自己维护ObjectContext的状态。我的界面如下:

/// <summary>
/// Contract for base generic repository
/// </summary>
public interface IRepository
{
    ActionResult SaveData<TEntity>(TEntity entityObj, bool commitTransaction) where TEntity : IEntity, new();

    ActionResult SaveData<TEntity>(ICollection<TEntity> entityObjects, bool commitTransaction) where TEntity : IEntity, new();

    ActionResult DeleteData<TEntity>(TEntity entityObj, bool commitTransaction) where TEntity : IEntity, new();

    ActionResult DeleteData<TEntity>(ICollection<TEntity> entityObjects, bool commitTransaction) where TEntity : IEntity, new();

    ICollection<TEntity> SelectAll<TEntity>() where TEntity : IEntity, new();
    ICollection<TEntity> SelectByCondition<TEntity>(Func<TEntity, bool> condition) where TEntity : IEntity, new();
}

ActionResult是一个类,它告诉我特定事务是否成功执行。现在我不想在存储库外维护事务状态。因此,每次保存/删除我们都可以传递bool值。第一次,可以在内部检查事务对象,然后当我调用我的上一个事务时,我可以发送committransaction true,这将调用SaveChanges()函数。

我的问题是:这种方法是否符合设计要求?我可以面对什么问题?

2 个答案:

答案 0 :(得分:3)

我发现这个实现存在很多问题。

  • 明确告知每个保存和删除操作是否提交是麻烦且容易出错的。只是意外地将一个操作设置为false并且你的break atomicy。控制交易不应该在那个级别进行。
  • SelectByCondition采用Func<T, bool>谓词,这意味着必须在内存中加载和过滤完整的数据库表。更好的设计是使用表达式树。
  • 你说你定义了一个“存储库类,它将在其自身内保持ObjectContext的状态”,但事实上你定义了一个工作单元:-),因为存储库用于一种类型的对象。 / LI>
  • 每个方法都采用TEntity类型参数,而这更适合于接口级别,因为那样您将遵循存储库设计模式。示例:IRepository<TEntity>。这样的设计会使使用类型安全。

看看this article。它描述了一种(相当抽象的)实现工作单元和存储库的方式,同时允许LINQ查询它们并允许它们是单元可测试的。

答案 1 :(得分:1)

您基本上创建了一个混合工作单元和存储库接口,从而打破了SRP。我建议您坚持使用工作单元通常通过IoC容器注入您的存储库。您仍然可以使用通用存储库。这是一个众所周知的模式,有许多社区样本专门围绕EF(检查我的单元测试EF的答案链接)。

在可能的情况下使用通用模式而不是烘焙自己的模式将更好地为团队现在或将来的任何开发人员提供服务。