IRepository<T>
インターフェイス、NewsRepository
クラス、News
エンティティを用意することで、リポジトリパターンの実装をほぼ完了しました。私が遭遇した問題は、一般的なメソッドを基本リポジトリクラスに抽象化しようとしたことでした。
NewsRepository
Getメソッドには特定のLinq式が含まれているため、Getメソッドを抽象化する方法が見つかりませんでした。
私の質問は:
1)public T Get(int id)
メソッドを基本クラスに抽象化するにはどうすればよいですか?これまで私が行った唯一の方法Expression<Func<T,bool>>
は、intの代わりに渡すことですが、各サブクラスはそれぞれの場合でほぼ同じ式を渡す必要があるため、一般的な動作を実際に抽象化することはできません。n => n.id == id
。
2) Updateメソッドの基本クラスにサブクラスのGetViolationsとmapメソッドを渡すにはどうすればよいですか?解決策はおそらくデリゲートを使用することだと思いますが、コンパイルする構文を取得できませんでした
これはコードの簡略化されたセットです。実際には、ここに示されている更新だけでなく、更新と挿入を行うSaveメソッドがあります。
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();
}
}