Загружает ли Fluent Nhibernate Lazy IList из критериев - PullRequest
0 голосов
/ 31 марта 2011

Я хочу сделать своеобразную «новостную ленту» в приложении моей компании.В этом сценарии действия пользователя будут генерировать «активность» различных видов, а другие пользователи будут видеть в своей «ленте новостей».

Однако «активность» относится не ко всем пользователям, и для определенияВ связи с этим у нас сложный фрагмент кода.

Вот мой класс Activity

public class Activity: IActivity
{
    public virtual int Id { get; set; }
    public virtual ActivityType Type { get; set; }
    public virtual User User { get; set; }
    public virtual bool IsVisibleToUser(User userLook)
    {
        // Complex business calculation etc.
        return true;
    }
}

Я хочу получать последние 10 новостей, которые видны Пользователю.Но так как таблица Activity будет довольно большой, а производительность - это проблема, я хочу сделать лучший совет об этом.

Что я собираюсь сделать, это получить 25 последних Activity и проверить, заполняем ли мысписок, чтобы показать пользователю.Например, если пользователю видны только 5 действий, я получу еще 25 действий и т. Д.

IList<Activity> resultList = session.CreateCriteria(typeof(Activity))
                                .SetMaxResults(25)
                                .AddOrder(Order.Desc("Id"))
                                .List<Activity>();

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

IList<Activity> resultList = session.CreateCriteria(typeof(Activity))
                                .AddOrder(Order.Desc("Id"))
                                .List<Activity>();

int count = 0;
foreach( Activity act in resultList){
    if (act.IsVisible(CurrentUser)){
        count++;
        // Do something with act
        if (count == 10)
            break;
    }
}

EDIT : Вот ActivityMapping для модели Activity.

public class ActivityMap : ClassMap<Activity>
{
    public ActivityMap()
    {
        Id(x => x.Id);
        Map(x => x.Type).CustomType(typeof(Int32));
        References(x => x.User).Nullable();
    }
}

Ответы [ 2 ]

3 голосов
/ 31 марта 2011

Если ваш вопрос о том, как будет выглядеть сгенерированный SQL, я думаю, будет:

SELECT 
   this_.Id as Id0_0_, 
   this_.ActivityTypeas ActivityType_0_0_, 
   --Other fields
FROM dbo.ActivityType this_ 
WHERE 
   --condition
ORDER BY 
   --condition

Поскольку вы упомянули, что количество действий огромно, вы можете использовать Критерии SetFirstResult и SetMaxResult.

SetFirstResult(int) указывает индекс первого элемента, который вы хотите получить, а SetMaxResult(int) указывает количество строк, которое вы хотите получить, 25 в вашем случае.

ToList будет загружать все записи в памяти одновременно.

[ОБНОВЛЕНИЕ] Если вам нужно, чтобы записи возвращались одна за другой, используйте Enumerable () -

Если вы ожидаете, что ваш запрос вернет очень большое количество объектов, но вы не собираетесь использовать их все, вы можете получить лучшую производительность от методов Enumerable (), которые возвращают System.Collections.IEnumerable. Итератор будет загружать объекты по требованию, используя идентификаторы, возвращаемые начальным запросом SQL (n + 1 выбирает общее количество).

Источник - Ссылка

2 голосов
/ 31 марта 2011

Нет, метод List () вытягивает все в память сразу.

...