Paulskit правильно сказал, что автор пытается написать паттерн Repository. А Lam правильно написал как сделать GenericRepository.
Пример обобщённого репозитория, кстати, есть здесь
www.asp.net/mvc/tutorials/getting-started-with-ef-...
Я в своём первом проекте его использовал. На самом деле, лично в моём понимании, это не очень хорошо.
Сейчас ваш метод возвращает объект по его ID. Предвижу, что следующим методом будет получение группы объектов и возвращение IQueryable. Такой подход невольно заставляет писать код выборки объектов где-нибудь (в контроллере, в слое сервиса), но не в репозитории, что приводит к путанице. На мой взляд, лучше делать не обобщённый репозиторий, а уникальный репозиторий для каждой сущности, необходимой для работы программы.
Предположим, что у вас есть класс BlogPost. Вы хотите иметь возможность загружать этот объект по ID, загружать вообще все эти объекты в память, загружать только часть этих объектов в память, загружать объекты с определённым условием и т.д. Для этого мы можете создать BlogPostRepository и написать в нём эти методы. Тогда ваша программа станет логичнее и понятнее. При работе с блогами вам не нужно будет каждый объявлять обобщённый репозиторий и городить поверх него запросы типа
var repository = new GenericRepository<BlogPost>();
var blogs = repository.GetAll().Skip(100).Take(10).OrderByDescending(c => c.Created);
Ну или как-то так (код примерный). Причём такие конструкции придётся городить в любом месте, где понадобится получить 10 последних блогов.
Проще сделать не обобщённый репозиторий, а специальный репозиторий для нужного объекта, тогда получится примерно так:
var repository = new BlogPostRepository();
var blogs = repository.GetTenTopBlogs();
В методе GetTenTopBlogs, соответственно, инкапсулируете логику выборки последних 10 блогов. Разумеется GetTenTopBlogs может иметь параметры (например количество блогов, которые нужно получить). Тут уже всё зависит от задач. И GetTopBlogs Должен возвращать IEnumerable, чтобы вызывающий код уже оперировал с сущностями в памяти, а не строил новые запросы к БД.
В целом код становится лаконичнее. Вам не нужно теперь каждый раз, чтобы что-то получить, объявлять обощённый репозиторий, тащить из него Queryable коллекцию и делать на ней выборку. Вы только вызываете метод и уже получаете результат. Теперь в вызывающих классах нет логики выборки.
Примерно так... :)
У Александра Бындю есть хорошие статьи на эту тему.
blog.byndyu.ru/2011/08/repository.html
Кстати, только заметил. Насколько я могу судить, репозиторий не должен знать об объекте DbContext. Это нужно для того, чтобы реализовать паттерн Unit Of Work. Представьте, что вы хотите совершить несколько транзакий (операций с репозиторием). Причём если хотя бы одна из них прошла неудачно, нужно всё откатить обратно. Предположим, что вы хотите сохранить 3 разных сущности в базу. Для этого вы написали свой обобщённый GenericRepository и объявили три переменных для каждой сущности. Причём у вас в этом GenericRepository будет функция Save (иначе как вы будете сохранять свои сущности).
Выходит, что каждый экземпляр класса GenericRepository будет содержать свою копию DbContext, и каждый раз после добавления сущности вы будете сохранять базу.
Единой транзакции не получится.
Чтобы получилась, нужно передавать DbContext в конструктор репозитория и ничего не сохранять в репозиториях. Т.е. вы где-то объявляете свой контекст, затем создаёте три репозитория и в каждый из них передаёте этот контекст. Делаете все операции, после чего сохраняете контекст в вызыывающем класе. Получается UoW. Хотя DbContext - это уже UnitOfWork.
По ссылке выше это тоже обсуждается (смотрите там рекоммендованные ссылки).
p.s. Paulskit дал хорошую ссылку, я как раз её пытался найти.
Lam тоже говорит правильно о том, что общие методы можно, конечно, вынести в обобщённый репозиторий. Только зачастую там этих методов - 1-2, а доброй трети сущностей эти методы вообще не понадобятся, так что я бы не стал делать лишнюю иерархию только для того, чтобы всем репозиториям назначить базовый класс.