29

作为 nHibernate 及其实用程序库 fluent nhibernate 的新用户,我正在努力学习足够多的知识,以使一个好的数据库变得危险。

我在理解Projections的概念时遇到了极大的困难。具体来说,他们到底是什么?

我确实对“什么是预测? ”进行了精确搜索。'和' nHibernate中的项目'和' nHibernate,Projections,Definition '等。我仍然很困惑。到目前为止,最有帮助的帖子是This other StackOverflow QuestionColin Ramsay 的这篇博客文章。但我仍然非常困惑。我对数据库的了解充其量仍然是入门级的。

我真的不明白预测是什么,为什么要使用它们,它们正在完成什么等。我在博客文章中看到他正在使用它们来获取整数列表(我假设是主键),以便他可以在不同的查询中使用它们,但这在它的运作方式和原因方面有点模糊。

4

3 回答 3

75

这是一个实际的例子。

假设您有一个在线商店,并且您的域类之一是Brand“Samsung”。这个类有一大堆与之关联的属性,可能是 integer Identity、 a Name、自由文本Description字段、对Vendor对象的引用等等。

现在假设您要显示一个菜单,其中列出了您的在线商店中提供的所有品牌。如果您只是这样做session.CreateCriteria<Brand>().List(),那么您确实会获得所有品牌。但是您也会从数据库中吸取所有长Description字段和对Vendors 的引用,并且您不需要它来显示菜单;你只需要NameIdentity。在性能方面,从数据库中吸取所有这些额外的数据会减慢速度并且是不必要的。

相反,您可以创建一个“投影”对象,其中仅包含IdentityName调用它,例如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);
}

现在你没有一个 s 的列表,Brand而是一个 s 的列表NameIdentityPair,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 ....)。

希望这可以帮助。

于 2011-05-26T15:11:45.510 回答
2

如果您熟悉 SQL,则投影是SELECT查询的子句,用于从可用结果中选择要返回的字段。

例如,假设您有一个Personwith FirstNameLastNameAddressPhone字段。如果您希望查询返回所有内容,则可以省略投影,就像SELECT * FROM Person在 SQL 中一样。如果您只想要名字和姓氏,您可以使用FirstName和创建一个投影LastName——这将是SELECT FirstName, LastName FROM PersonSQL 术语。

于 2011-05-26T15:08:42.077 回答
1

您可以使用投影来调用 SUM、COUNT... 等 sql 函数或选择单个字段而不返回实体。

“...仅检索一个或多个实体的属性,而无需在事务范围内加载实体本身的开销。这有时称为报告查询;更正确地称为投影。” [NHibernate 在行动]

于 2011-05-26T14:43:03.723 回答