IRepository<T>通过拥有一个接口、一个NewsRepository类和一个News实体,我几乎已经完成了我的存储库模式的实现。我遇到的问题是试图将常用方法抽象为基础 Repository 类。
我找不到一种方法来抽象 Get 方法,NewsRepository因为它包含特定的 Linq 表达式。
我的问题是:
1)请问如何将public T Get(int id)方法抽象为基类?到目前为止,我完成它的唯一方法是传入Expression<Func<T,bool>>而不是 int,但是这并没有真正抽象出常见的行为,因为每个子类仍然需要传入一个在每种情况下几乎相同的表达式,即n => n.id == id.
2)如何将子类 GetViolations 和 map 方法传递到 Update 方法的基类中?我想解决方案可能是使用委托,但我无法获得编译的语法
这是一组简化的代码——实际上我有一个 Save 方法,它执行 Update 和 Insert 而不仅仅是这里显示的 Update。
public interface IRepository<T>
{
    T Get(int id);
    void Update(T item);
}
public class NewsRepository : IRepository<News>
{
    private Table<News> _newsTable;
    public NewsRepository(string connectionString)
    {
        _newsTable = new DataContext(connectionString).GetTable<News>();
    }
    public News Get(int id)
    {
        return _newsTable.SingleOrDefault(n => n.NewsId == id);
    }
    public void Update(News item)
    {
        var errors = item.GetRuleViolations();
        if (errors.Count > 0)
            throw new RuleException(errors);
        News dbNews = _newsTable.SingleOrDefault(n => n.NewsId == item.NewsId);
        map(dbNews, item);
        _newsTable.Context.SubmitChanges();
    }
    private void map(News dbNews, News news)
    {
        dbNews.Title = news.Title;
        dbNews.Article = news.Article;
    }
}
public class Repository<T> where T : class
{
    protected Table<T> _table;
    public Repository(Table<T> t)
    {
        _table = t;
    }
    //How do i do this??! - This doesn't compile due to T no having a NewsId
    public T Get(int id)
    {
    return _table.SingleOrDefault(n => n.NewsId == id);
    }
    //This seems to be a solution, but it's not really abstracting common behaviour as each
    //sub-class will still need to pass in the same linq expression...
    public T Get(Expression<Func<T,bool>> ex)
    {
        return _table.SingleOrDefault(ex);
    }
    public void Update(T item)
    {
        //How is it possible to pass in the GetRuleViolations and map functions to this method?
        var errors = item.GetRuleViolations();
        if (errors.Count > 0)
            throw new RuleException(errors);
        T dbNews = _table.SingleOrDefault(n => n.NewsId == item.NewsId);
        map(dbNews, item);
        _table.Context.SubmitChanges();
    }
}