Может кто-нибудь лучше объяснить, что такое «проекции» в nHibernate? - PullRequest
29 голосов
/ 26 мая 2011

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

У меня исключительно большие трудности с пониманием концепции Проекции . В частности, Что они в мире?

Я буквально выполнил точный поиск по ' Что такое проекции? ' и ' Проекты в nHibernate ' и ' nHibernate, Projection, Definition ' и т. Д. И я все еще очень растерялся. Наиболее полезные сообщения на данный момент: Этот другой вопрос StackOverflow и Это сообщение в блоге Колина Рамсея . Но я все еще в замешательстве. Мои знания баз данных все еще находятся на начальном уровне в лучшем случае.

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

Ответы [ 3 ]

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

Вот практический пример.

Допустим, у вас есть интернет-магазин, и один из ваших классов доменов Brand похож на "Samsung". С этим классом связано множество свойств, возможно, целое число Identity, поле Name, поле произвольного текста Description, ссылка на объект Vendor и т. Д.

Теперь предположим, что вы хотите отобразить меню со списком всех брендов, предлагаемых в вашем интернет-магазине. Если вы просто сделаете session.CreateCriteria<Brand>().List(), тогда вы действительно получите все бренды. Но вы также высосали все длинные поля Description и ссылки на Vendor s из базы данных, и вам не нужно это для отображения меню; вам просто нужны Name и Identity. С точки зрения производительности высасывание всех этих дополнительных данных из базы данных замедляет работу и не является необходимым.

Вместо этого вы можете создать «проекционный» объект, содержащий только Identity и Name, вызывающие его, скажем, NameIdentityPair:

public class NameIdentityPair
{
    public int Identity { get; set; }
    public string Name { get; set; }
}

И вы можете сказать NHibernate, чтобы он выбирал только те данные, которые вам действительно нужны для выполнения поставленной задачи, сказав ему преобразовать набор результатов в вашу проекцию:

var brandProjections = this.session.CreateCriteria<Brand>()
    .SetProjection(Projections.ProjectionList()
        .Add(Projections.Property("Name"), "Name")
        .Add(Projections.Property("Identity"), "Identity"))
    .SetResultTransformer(Transformers.AliasToBean<NameIdentityPair>())
    .List<NameIdentityPair>();

foreach (var brandProjection in brandProjections)
{
    Console.WriteLine(
        "Identity: {0}, Name: {1}", 
        brandProjection.Identity, 
        brandProjection.Name);
}

Теперь у вас нет списка Brand s, но вместо этого есть список NameIdentityPair s, и NHibernate будет выдавать только SQL-оператор, такой как SELECT b.Identity, b.Name from dbo.Brand b, чтобы получить эту проекцию, в отличие от массивного SQL утверждение, которое захватывает все необходимое для увлажнения объекта Brand (например, SELECT b.Identity, b.Name, b.Description from dbo.brand b left join dbo.vendor v ....).

Надеюсь, это поможет.

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

Если вы знакомы с SQL, проекция - это предложение SELECT запроса, которое используется для выбора полей из доступных результатов для возврата.

Например, предположим, что у вас есть Person с полями FirstName, LastName, Address и Phone.Если вы хотите, чтобы запрос все возвращал, вы можете отключить проекцию, которая похожа на SELECT * FROM Person в SQL.Если вам просто нужны имя и фамилия, вы должны создать проекцию с FirstName и LastName - что будет SELECT FirstName, LastName FROM Person в терминах SQL.

1 голос
/ 26 мая 2011

Вы можете использовать проекции для вызова функций sql, таких как SUM, COUNT ... или выбрать отдельные поля без возврата объекта.

"... Извлечение только свойств объекта или объектов без нагрузки на загрузку Сам объект в транзакционной области. Это иногда называют отчетом запрос; это более правильно называется проекцией. "[NHibernate в действии]

...