【问题标题】:EF4: how to use a generic repository pattern ?EF4:如何使用通用存储库模式?
【发布时间】:2012-06-22 01:50:27
【问题描述】:

我正在尝试通过使用我可以继承的通用存储库来简化我现有的存储库。问题是我不知道如何编写一些基类方法。我目前有:

public interface IRepository<T> : IDisposable where T : class
{
    IQueryable<T> GetAll();
    T GetSingle(int id);
    T GetSingle(string slug);
    void Save(T entity);
}

public class HGRepository<T> : IRepository<T> where T : class
{
    protected HGEntities _siteDB;
    protected IObjectSet<T> _objectSet;

    public HGRepository(HGEntities context)
    {
        _siteDB = context;
        _objectSet = _siteDB.CreateObjectSet<T>();
    }

    public IQueryable<T> GetAll()
    {
        return _objectSet;
    }

    public T GetSingle(int id)
    {
        return null;
    }

    public T GetSingle(string slug)
    {
        return null;
    }

    public void Save(T entity)
    {
        // code to save entity
    }

    public void Dispose()
    {
        _siteDB = null;
    }
}

我的困惑在于我的 GetSingle()Save() 方法。他们需要依赖与T 的每种类型略有不同的信息。我的非通用回购示例:

public Article GetArticle(int id)
{
    return _siteDB.Articles.SingleOrDefault(a => a.ArticleID == id);
}

public Article GetArticle(string slug)
{
    return _siteDB.Articles.SingleOrDefault(a => a.Slug == slug);
}

public void SaveArticle(Article article)
{
    if (article.ArticleID > 0)
    {
        _siteDB.ObjectStateManager.ChangeObjectState(article, System.Data.EntityState.Modified);
    }
    else
    {
        _siteDB.Articles.AddObject(article);
    }

    _siteDB.SaveChanges();
}

如您所见,文章有自己的特定 ID。我的其他实体也是如此(例如,新闻项目具有 NewsID 属性)。

我怎样才能使抽象的基础方法可以协调成更具体的版本?

【问题讨论】:

  • 第一个问题应该是why use repository
  • 很好的链接。也就是说,我的项目相当简单,而我的后端实际上只是简单的 CRUD 功能。里面没有 DDD。
  • 更有理由放弃沙包代码,不是吗?
  • 嗯……也许吧。对我来说,将诸如我用来保存实体的代码之类的东西(我上面的问题中的一个示例)隐藏在方法接口后面会更干净。但是,另一方面,GetByXXX 方法让我想起了丑陋的 PHP 样板。

标签: c#-4.0 asp.net-mvc-2 entity-framework-4 repository-pattern


【解决方案1】:

您可以为您的GetSingle 方法设置一个通用的expression 参数:

public interface IRepository<T> : IDisposable where T : class
{
    ....
    T GetSingle(Expression<Func<T, bool>> filter);
    void Save(T entity);
}

HGRepository&lt;T&gt;:

public T GetSingle(Expression<Func<T, bool>> filter)
{
        return _objectSet.Where(filter).SingleOrDefault();
}

及用法:

IRepository<Article> rep = new HGRepository<Article>();
return rep.GetSingle(p => p.Slug == slug);

如果您有通用接口/存储库类未涵盖的特定场景,您可以创建从通用接口/类继承的新接口/类:

public interface IArticleRepository : IRepository<Article>
{
   ...
}

public class ArticleRepository : HGRepository<Article>, IArticleRepository
{
   ...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多