我几乎完成了一个IRepository<T>
接口,一个NewsRepository
类和一个News
实体来实现我的存储库模式。我遇到的问题是试图将常见方法抽象到基本Repository类。如何使用接口,基础和具体实现存储库模式
我找不到方法来抽象NewsRepository
中的Get方法,因为它包含特定的Linq表达式。
我的问题是:
1)我如何抽象基类的public T Get(int id)
方法好吗?到目前为止,我所做的唯一方法是传递Expression<Func<T,bool>>
而不是int,但是然后没有真正地抽象出常见的行为,因为每个子类仍然需要传递一个几乎相同的表达式即n => n.id == id
。
2)如何在Update方法中传入子类GetViolations和map方法的基类?我想象的解决方案可能是通过使用委托,但我无法获得编译的语法
这是一个简化的代码集 - 在实践中我有一个保存方法,更新和插入,而不仅仅是更新显示在这里。
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();
}
}