Вопрос

Допустим, у меня есть модель предметной области с классом Blog, у которого есть свойство BlogEntries (которое содержит объекты типа BlogEntry). Если у меня есть модель базы данных с двумя таблицами " Блог " и " BlogEntry " ;, не исключено, что у меня есть 1000 записей для блога. Если бы я показывал блог на веб-сайте, я бы хотел отображать только 20 записей в блоге за раз, поэтому мне пришлось бы использовать какую-то подкачку страниц. Я, очевидно, не хочу, чтобы 1000 записей постоянно выбирались из БД.

Как бы я поступил так? Должно ли свойство BlogEntries быть даже в объекте домена Blog или, возможно, в репозитории? Я все еще хотел бы иметь возможность добавлять записи в блоге, а также получать постраничный результат из существующих. Как будет выглядеть отображение NHibernate?

Блог / BlogEntry - это всего лишь пример, он также может быть примером клиент / заказ или любым другим сценарием мастер / подробности.

Пожалуйста, просветите меня!

Это было полезно?

Решение

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

public class Blog
{
    public int ID {get;set;}
    // other stuff
}

public class BlogEntry
{
    public int ID {get;set;}
    public int BlogID {get;set;}
}

public class BlogEntryRepository
{
    public IEnumerable<BlogEntry> FindByBlogID(
        int blogID, int pageIndex, int pageSize) 
    {
        // implementation
    }
}

В качестве альтернативы (также с BlogEntry, смоделированным как Aggregate root), вы можете добавить коллекцию BlogEntryID в ваш класс Blog. Это было бы лучше, чем иметь сами экземпляры BlogEntry в классе Blog, поскольку у вас было бы гораздо меньше данных для загрузки, когда вы хотите получить экземпляр Blog. С помощью этих идентификаторов вы можете выбрать их подмножество и передать их в метод репозитория BlogEntry, который принимает коллекцию идентификаторов. Другими словами, в вашем домене будет немного больше логики для поддержки подкачки страниц и более общий метод получения в хранилище.

public class Blog
{
    public int ID {get;set;}
    public IEnumerable<int> BlogEntryIDs {get;set;}
    // other stuff
}

public class BlogEntry
{
    public int ID {get;set;}
    public int BlogID {get;set;}
}

public class BlogEntryRepository
{
    public IEnumerable<BlogEntry> Get(IEnumerable<int> blogEntryIDs) 
    {
        // implementation
    }
}

Использование для этого подхода будет похоже на

// get the second page
var entries = 
  blogEntryRepo.Get(blog.BlogEntryIDs).Skip(1 * PAGE_SIZE).Take(PAGE_SIZE);

В базе данных вы должны вернуть несколько строк, по одной на каждую запись в блоге. (Я также предпочитаю возвращать несколько результирующих наборов, чтобы получить все строки из всех связанных таблиц в одном цикле обработки базы данных. Я также использую функцию SQL 2005 ROW_VERSION для включения подкачки базы данных.)

Как правило, я предпочитаю второй метод, если только при обычном использовании не отображаются запрещенные количества (например, более пары тысяч) экземпляров BlogEntry, связанных с блогом. Множество слишком большого числа int заставит меня опасаться производительности и памяти.

Другие советы

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

Редактировать: зачем понижать голос? Это неправильно?

Для сбора записей в блоге вы можете использовать BatchSize. атрибут. Это позволит вам не выбирать всю коллекцию из базы данных, только необходимые значения.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top