Должны ли репозитории реализовывать IQueryable <T>? - PullRequest
27 голосов
/ 03 октября 2008

Я рассматриваю один из двух интерфейсов IRepository, один из которых является потомком IQueryable, а другой содержит IQueryable.

Как это:

public interface IRepository<T> : IQueryable<T>
{
    T Save(T entity);
    void Delete(T entity);
}

Или это:

public interface IRepository<T>
{
    T Save(T entity);
    void Delete(T entity);
    IQueryable<T> Query();
}

Использование LINQ будет:

from dos
in ServiceLocator.Current.GetInstance<IRepository<DomainObject>>()
where dos.Id == id
select dos

Или ...

from dos
in ServiceLocator.Current.GetInstance<IRepository<DomainObject>>().Query
where dos.Id == id
select dos

Я вроде как первый, но издеваться над ним проблематично. Как другие люди внедрили LINQable, поддельные репозитории?

Ответы [ 3 ]

14 голосов
/ 03 октября 2008

Зависит от того, хотите ли вы иметь отношения Has-A или Is-A.

Первый - это отношения Is-A. Интерфейс IRepository является интерфейсом IQueryable. Второе - это хас-а. IRepository имеет интерфейс IQueryable. В процессе написания этой статьи мне больше нравится вторая, чем первая, просто потому, что когда вы используете ваш второй IRepository, я могу дать метод Query () НИЧЕГО, который возвращает IQueryable. Для меня это более гибко, чем первая реализация.

8 голосов
/ 16 марта 2011

Лично я использую Repository Pattern, чтобы вернуть все элементы из хранилища как IQueryable. Благодаря этому мой уровень репозитория стал очень легким, небольшим ... с сервисным уровнем (который использует уровень Repository) теперь можно открывать для всех типов манипулирования запросами.

По сути, вся моя логика теперь находится на сервисном уровне (который не знает, какой тип репозитория он будет использовать ... и не хочет знать

например. Более или менее псевдо-код, поскольку я вспоминаю, что мы сделали в нашем коде, и упрощаю его для этого ответа ...

public interface IRepository<T>
{
    IQueryable<T> Find();
    void Save(T entity);
    void Delete(T entity);
}

и иметь хранилище пользователя ...

public class UserRepository : IRepository<User>
{
    public IQueryable<User> Find()
    {
        // Context is some Entity Framework context or 
        // Linq-to-Sql or NHib or an Xml file, etc...
        // I didn't bother adding this, to this example code.
        return context.Users().AsQueryable();
    }

    // ... etc
}

и теперь для лучшего бита :)

public void UserServices : IUserServices
{
    private readonly IRepository<User> _userRepository;

    public UserServices(IRepository<User> userRepository)
    {
        _userRepository = userRepository;
    }

    public User FindById(int userId)
    {
        return _userRepository.Find()
            .WithUserId(userId)
            .SingleOrDefault();  // <-- This will be null, if the 
                                 //     user doesn't exist
                                 //     in the repository.
    }

    // Note: some people might not want the FindBySingle method because this
    //       uber method can do that, also. But i wanted to show u the power
    //       of having the Repository return an IQuerable.
    public User FindSingle(Expression<Func<User, bool>> predicate)
    {
        return _userRepository
            .Find()
            .SingleOrDefault(predicate);
    }
}

Бонусные баллы: WTF равен WithUserId(userId) в методе FindById? Это Труба и фильтр . Используйте их :) любите их :) обнимите их :) Они делают ваш код SOOO очень читабельным :) Теперь, если вы хотите знать, что это делает ... это метод расширения.

public static User WithId(this IQueryable<User> source, int userId)
{
    return source.Where(u => u.UserId == userId).SingleOrDefault();
}

HTH, хотя этот вопрос ... ну ... почти два года :) 1023 *

0 голосов
/ 03 июня 2009

Вы всегда можете быстро написать что-то против List, это не издевательство с использованием фиктивного фреймворка, но оно, безусловно, прекрасно работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...