【发布时间】:2016-08-09 14:44:57
【问题描述】:
我正在尝试在我的应用程序中实现最小的通用存储库模式。我有一个非常小的接口用于查询和保存数据:
public interface IRepository
{
IQueryable<TEntity> Query<TEntity>()
where TEntity: BaseEntity;
void Save<TEntity>(TEntity entity)
where TEntity : BaseEntity;
}
BaseEntity 是我将存储在存储库中的所有对象的基类:
public abstract class BaseEntity
{
public Guid Id { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime UpdatedDate { get; set; }
}
我试图使用 Entity Framework 找到这样一个简单存储库的工作实现,但发现起来非常困难(人们正在使用 UnitOfWork 和其他使实现比我想要的更复杂的东西)。
所以我创建了我能想到的绝对最小的实现:
public class EfRepository : DbContext, IRepository
{
public IQueryable<TEntity> Query<TEntity>() where TEntity : BaseEntity
{
return this.Set<TEntity>();
}
public void Save<TEntity>(TEntity entity) where TEntity : BaseEntity
{
if (entity.Id == default(Guid))
{
entity.Id = Guid.NewGuid();
this.Set<TEntity>().Add(entity);
}
else
{
this.Entry(entity).State = EntityState.Modified;
}
this.SaveChanges();
}
public DbSet<User> Users { get; set; } // User is a subclass of BaseEntity
//Other DbSet's...
}
现在,我的问题是这样的实现是否正确。我之所以问,是因为我是 Entity Framework 的新手,我担心在使用此类存储库时可能出现性能问题或可能出错的事情。
注意:我尝试这样做有两个原因:
- 出于测试目的,以便我可以在我的单元测试项目中创建存储库的模拟
- 将来我可能不得不切换到另一个 ORM,并且我希望让这种过渡尽可能简单。
【问题讨论】:
-
如果您只是轻描淡写并且有性能问题,那么 EF 是否是正确的 ORM 可能值得考虑。从个人经验来看,我没有发现 EF 在我使用过的任何项目中都表现得非常好,而且保持其映射与数据库或代码一致有点笨拙(取决于您选择的路径、代码或数据库优先)。每当有人提到 EF 时,我认识的任何在高吞吐量环境中工作的人都会畏缩不前。
-
真正的问题是:既然 EF 已经 实现了存储库 (
DbSet<T>) 和工作单元 (DbContext) 模式 - 为什么要重新发明轮子呢上面还有一层?? -
@marc_s,我有两个原因 :) 请看我的编辑
-
原因 #1 在 EF6 中是不必要的 - 您可以使用 Rowan Miller 的 EntityFramework.Testing NuGet 包轻松模拟
DbSet<T>和DbContext.... -
我仍在等待理由 2 的真实示例。YAGNI
标签: c# entity-framework repository-pattern