Создать репозиторий без использования IQueryable для спецификации - PullRequest
0 голосов
/ 24 марта 2011

Я недавно изучал DDD, репозитории и шаблон спецификации, и после прочтения множества блогов и примеров я пытаюсь создать репозиторий, которым я доволен.

Ядовольно новичок в этом, так что до сих пор пытаюсь понять концепции, так голые со мной.До недавнего времени я выставлял IQueryable в своих репозиториях, но после того, как понял, что IQueryable - это утечка абстракции, потому что это отложенное выполнение и фактически пересекает границу из уровня данных, я изменил его, так что мои репозитории вместо этого возвращают IEnumerable.

Так что у меня может быть что-то вроде этого, например: -

public interface IUserRepository
{
    IEnumerable<User> All();

    void Save(User item);
    void Delete(User item);
}

Я подумал, хорошо, что это хорошо, но что если я захочу отфильтровать данные по моему имени или по электронной почте?После прочтения поста в блоге я реализовал способ передачи ICriteria в метод All ().

public IEnumerable<TEntity> All(ICriteria<TEntity> criteria)
{
    return criteria.BuildQueryFrom(Set).ToList();
    // Set is a DbSet from EntityFramework
}

И пример класса критериев: -

public class AccountById : ICriteria<Account>
{
    private readonly int _id;

    public AccountById(int id)
    {
        _id = id;
    }

    IQueryable<Account> ICriteria<Account>.BuildQueryFrom(DbSet<Account> dbSet)
    {
        return from entity in dbSet
               where entity.Id == _id
               select entity;
    }
}

Это прекрасно работает, и я могусоздайте эти классы критериев для удовлетворения моих требований и передайте их в репозитории, и все работает хорошо.

Одна вещь, которая мне не нравится, связана с IQueryable, потому что я должен использовать ORM, который поддерживает Linq, так что еслиЯ хотел использовать SqlCommand в своем репозитории для, скажем, повышения производительности или чтобы я мог писать более чистый SQL, а не сгенерированный ORM SQL, как бы я это сделал?

Я также хотел бы избежать написанияновый метод для каждого фильтра, такой как FindById, FindByUsername, FindByEmail и т. д.

Итак, в основном, как я могу создать репозиторий, который позволяет мне указывать критерии, которые я хочу выбрать, без использования IQueryable, чтобы он все равно работал,использовал EF, nHibernate или просто SqlCommand?Я изо всех сил пытаюсь найти пример, который использует SqlCommand и шаблон спецификации.

Как люди делали это до ORM?

Заранее спасибо, надеясь, что кто-то может показать мне свет!:)

1 Ответ

0 голосов
/ 24 марта 2011

Лично я не возражаю против того, чтобы IQueryable была утечкой абстракции, потому что она позволяет мне писать запросы LINQ на моем уровне обслуживания и, следовательно, иметь более тестируемый код. Пока объекты, которые реализуют IQueryable, хранятся внутри уровня обслуживания (т.е. не возвращают их на уровень представления), я не вижу проблемы. Это максимизирует тестируемость вашего приложения. Например, мой блог о тестируемых репозиториях LINQified .

...