Не уверены, как реализовать конкретное расширение для nHibernate с помощью LINQ - PullRequest
2 голосов
/ 26 мая 2011

В блоге довольно популярного сайта ayende.com блог . Есть раздел, который бросается в глаза очень специфическим образом.

Близко к концупост, он делает комментарий, цитируемый с сайта

Ответ, который я даю для таких вещей, как «ну, как я могу применить фильтрацию безопасности», состоит в том, что вы добавляете это в метод расширения и делаетекак-то так:

var query = 
  (
        from post in session.Query<Post>()
        where post.DueDate > DateTime.Now 
        select post
   )
   .FilterAccordingToUserPermissions(CurrentUser)
   .ToList();

Мне очень нравится этот подход, если честно. Мне он кажется очень чистым. Но из-за моей неопытности и недостатка знаний ни о методах расширения, ни о nHibernate, яне могу воспроизвести его.

var query = ( from post in session.Query<Post>() ...

это говорит мне о том, что используемый объект является NHibernate.Linq.Query<T> объектом. Я в основном использую QueryOver<T> в своих проектах с целью их проецированияна Futures, но я отвлекся ...

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

Вот то, чего я не понимаю;

  1. Я не понимаю, как расширить объект Query<T> или QueryOver<T>.
  2. Если я продлилобъекты, я не понимаю, как заставить это расширение повлиять / фильтровать поиск в базе данных.
  3. Если я смогу повлиять на поиск в базе данных, я не понимаю, как это повлияет на производительность.
  4. Я не очень понимаю, откуда взялся CurrentUser.Мне кажется, что для этого потребуется еще одна поездка в базу данных, и это опять-таки идет вразрез с тем, что nhprof и большинство книг, которые я читал, говорят мне (не совершайте несколько поездок за однуоперация).

пункт 3 - тот, который сбивает меня с толку больше всего.Единственное, о чем я могу думать, это то, что этот метод берет запрос и запускает его, затем фильтрует, а затем возвращает результаты.Это кажется мне нелогичным (и, похоже, против многих вещей, которые я видел на сайте ayende.com/blog, поскольку он наследует множество необязательных обращений к базе данных)

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

Ответы [ 2 ]

2 голосов
/ 26 мая 2011

Да, вы правы, вопрос немного расплывчат, но я попытаюсь ответить на ваши вопросы.

1) На самом деле вы не расширяете объект Query.Расширение, которое вы пишете, будет на самом деле против IQueryable, так что ...

    public static IQueryable<Post> MySecurityExtension(this IQueryable<Post> repository, string currentUser)
    {
        return repository.Where(p => p.User == currentUser);
    }

Очевидно, что ваши критерии безопасности будут более сложными, чем это.

2) Метод расширения позволяетдобавить дополнительные критерии в IQueryable, который был передан. Эти дополнительные критерии затем встроены в sql механизмом NH Query при выполнении этого запроса.

3) Производительность, очевидно, связана с запросом, который вы пишете, болеесложный запрос будет выполняться медленнее.Однако сам по себе метод расширения не влияет на производительность.Важно понимать, что запрос не выполняется до тех пор, пока весь запрос не будет построен .Обычно это инициируется .ToList (), Single (), First () или другими операторами, которые фактически перечисляют запрашиваемый.

4) CurrentUser исходит от вас и может потребоваться получить его из базы данных.заранее.Но вам, вероятно, придется делать это в любом случае в вашем приложении.

0 голосов
/ 26 мая 2011

Метод расширения не имеет ничего общего с NHibernate.Он просто используется для фильтрации (или «применения политики безопасности») IEnumerable<Post>, возвращаемого запросом NHibernate.

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

Метод расширения будет определен в статическом классе следующим образом:

public IEnumerable<Post> FilterAccordingToUserPermissions(this IEnumerable<post> list, CurrentUser user)
{
    // implementation
}

И не забывайте, что глупого вопроса не бывает:)

...