2012-06-29 5 views
0

С шаблоном репозитория и ViewModels, как вы создаете запросы к базе данных, если вы не хотите, чтобы исходные объекты базы данных протекали вне репозитория? Как я могу создавать запросы без загрузки ВСЕ базы данных в памяти и использования LINQ to Objects? Я не могу разоблачить IQueryable для остальной части приложения.Шаблон хранилища, ViewModel и ORM

Например, с EF У меня есть группа POCOs с несколькими свойствами, которые соответствуют полям db, но также некоторые вещи для работы вокруг перечислений, которые не поддерживаются напрямую (на данный момент), а также идентификаторы внешнего ключа для предотвращения N + 1 и более простой запрос и так далее. Я не хочу, чтобы они просачивались в остальную часть приложения, я хочу, чтобы приложение просто просматривало обычный граф объектов.

public class DbUser 
{ 
    public int Id { get; set; } 
    public string Name { get set; } 

    public int GroupId { get; set; } 
    public DbGroup Group { get; set; } 

    public ICollection<DbComment> { get; set; } 
} 

public class User 
{ 
    public int Id { get; set; } 
    public string Name { get set; } 

    public Group Group { get; set; } 
    public ICollection<Comment> { get; set; } 
} 

Проблема здесь мое хранилище будет внутренне использовать EF для выполнения запросов (и в памяти материал при тестировании блока). Но как мне реализовать IQueryable<User> FindAll()? Я не могу просто вернуть dbContext.Users.Select(u => new User(u)), так как в этом случае я теряю все возможные возможности запроса; он просто загрузит всю коллекцию пользователей в память, преобразует все типы в User из DbUser, а затем построит запросы LINQ в коллекции в памяти - это ужасно неэффективно.

Я не могу просто создавать запросы в репозитории. На некоторых страницах у меня есть запросы, которые выбирают несколько полей, но также вычисляют некоторые сложные вещи из других связанных объектов, фильтруют их на основе результата (например, количество комментариев с положительной оценкой), но я также нуждаюсь в этом в приложении. Я мог бы выбрать все объекты, используемые для получения сложного материала и вернуть их в приложение (но не как объекты db), но это означало бы выбор большого количества данных.

В принципе, как я предотвратить объекты базы данных от загрязнения остальной части приложения с их хлама и писак, в то же время сохраняя возможность создавать запросы вне хранилища?

+0

В частности, я использую Entity Framework, чьи DbContext и DbSet реализуют репозиторий и блок работы; следует ли использовать объекты EF в качестве моделей и издеваться над контекстом и устанавливать во время тестирования? Это то, к чему я склоняюсь. – CMircea

ответ

1

CQRS (Ответственность за ответную реакцию командного запроса) решает эту проблему. У вас есть «реальная» модель, модель домена, со всеми бизнес-правилами и все такое, а также с моделью «запрос-ony», которая в основном представляет собой простой poco (который может использоваться непосредственно по Views), который будет возвращен специализированный репозиторий только для запросов.

Модель существования (объекты EF) используется только для «разговора» с db, репозитории всегда возвращаются или имеют дело с объектами домена/приложения. В принципе, вам нужно сопоставить объекты EF с доменными (и наоборот) при сохранении. Таким образом, у вас будут отдельные модели с каждой целью.

Смежные вопросы