Фильтрация содержимого загруженной коллекции с помощью NHibernate - PullRequest
1 голос
/ 17 октября 2011

У меня есть модель домена, которая включает в себя что-то вроде этого:

public class Customer : EntityBase<Customer>, IAggregateRoot
{
    public IList<Comment> Comments { get; set; }
}

public class Comment : EntityBase<Comment>
{
    public User CreatedBy { get; set; }
    public bool Private { get; set; }
}

У меня есть сервисный уровень, через который я получаю эти объекты, и среди аргументов, передаваемых этому сервисному уровню, есть тот, кто запрашивающий пользователь.

То, что я хотел бы сделать, это иметь возможность создать DetachedCriteria на уровне сервиса, который ограничил бы количество элементов Comment, возвращаемых для данного клиента, чтобы пользователь не отображал комментарии, которыене принадлежат им и помечены как личные.

Я пытался сделать что-то вроде этого:

criteria.CreateCriteria("Comments")
    .Add(Restrictions.Or(Restrictions.Eq("Private", false),
                         Restrictions.And(Restrictions.Eq("Private", true),
                                          Restrictions.Eq("CreatedBy.Id", requestingUser.Id))));

Но это не распространяется на лениво загруженные комментарии.

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

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

Есть идеи, возможно ли это с помощью DetachedCriteria?Есть ли другие способы сделать это?

1 Ответ

1 голос
/ 17 октября 2011

Мне кажется, что сама сущность предоставляет другой набор значений для свойства коллекции на основе некоторого внешнего значения.

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

Для лучшего соответствия вашему текущемухотя в модели, у меня будет вызов, который вы в данный момент делаете, чтобы объекты возвращали модель представления, а не только объекты;

public class PostForUser
{
    public Post Post {get; set;}
    public User User {get; set;}
    public IList<Comment> Comments}
}

А затем в вашем методе обслуживания (я делаю некоторые предположения здесь)

public PostForUser GetPost(int postId, User requestingUser){

   ...
}

Затем вы могли бы создать и заполнить модель представления PostForUser наиболее эффективным способом, возможно, по отдельным критериям или с помощью одного запроса и преобразователя DistinctRootEntity (вы можете оставить фактическое свойство комментариев для отложенной загрузки)., как вы, вероятно, не будете использовать его)

...