Вот практический пример.
Допустим, у вас есть интернет-магазин, и один из ваших классов доменов 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 ....
).
Надеюсь, это поможет.