简体   繁体   English

有人可以更好地解释 nHibernate 中的“投影”是什么吗?

[英]Can someone better explain what 'Projections' are in nHibernate?

As a new user of nHibernate and its utility library, fluent nhibernate, I am trying to learn enough to be dangerous with a good database.作为 nHibernate 及其实用程序库 fluent nhibernate 的新用户,我正在努力学习足够多的知识,以至于使用一个好的数据库是危险的。

I am having an exceptionally great deal of difficulty understanding the concept of Projections .我在理解Projections的概念时遇到了极大的困难。 Specifically, What in the world are they?具体来说,他们到底是什么?

I have literally done exact searches on ' What are projections?我确实对“什么是预测? ”进行了精确搜索。 ' and ' Projects in nHibernate ' and ' nHibernate, Projections, Definition ', etc. And I am still very confused. '和' nHibernate '和' nHibernate,Projections,Definition '等中的项目。我仍然很困惑。 The most helpful posts so far are This other StackOverflow Question and This Blog Post by Colin Ramsay .到目前为止,最有帮助的帖子是This other StackOverflow QuestionColin Ramsay 的这篇博客文章 But I am still vastly confused.但我仍然非常困惑。 My knowledge of databases is still entry-level at best.我对数据库的了解充其量仍然是入门级的。

I do not really understand what projections are, why I would want to use them, what they are accomplishing, etc. I see in the blog post that he is using them to get a list of integers (I presume Primary Keys) so that he can use them in a different query, but this is kind of nebulous in the way it is functioning and the why.我真的不明白预测是什么,为什么要使用它们,它们正在完成什么等。我在博客文章中看到他正在使用它们来获取整数列表(我假设是主键),以便他可以在不同的查询中使用它们,但这在它的运作方式和原因方面有点模糊。

Here's a practical example.这是一个实际的例子。

Let's say that you have an online store and one of your domain classes is a Brand like "Samsung".假设您有一个在线商店,并且您的域类之一是“三星”之类的Brand This class has a boatload of properties associated with it, perhaps an integer Identity , a Name , a free-text Description field, a reference to a Vendor object, and so on.这个 class 有很多与之相关的属性,可能是一个 integer Identity ,一个Name ,一个自由文本Description字段,对Vendor object 的引用,等等。

Now let's say that you want to display a menu with a list of all the brands offered on your online store.现在假设您要显示一个菜单,其中列出了您的在线商店中提供的所有品牌。 If you just do session.CreateCriteria<Brand>().List() , then you are indeed going to get all of the brands.如果你只做session.CreateCriteria<Brand>().List() ,那么你确实会得到所有的品牌。 But you'll also have sucked all of the long Description fields and references to Vendor s from the database, and you don't need that to display a menu;但是你也会从数据库中吸取所有长的Description字段和对Vendor的引用,并且你不需要它来显示菜单; you just need the Name and the Identity .你只需要NameIdentity Performance-wise, sucking all of this extra data down from the database slows things down and is unnecessary.在性能方面,从数据库中吸取所有这些额外的数据会减慢速度并且是不必要的。

Instead, you can create a "projection" object that contains just the Identity and the Name calling it, say, NameIdentityPair :相反,您可以创建一个“投影” object ,其中仅包含Identity和调用它的Name ,例如NameIdentityPair

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

And you could tell NHibernate to only select the data that you really need to perform the task at hand by telling it to transform the result set onto your projection:你可以告诉 NHibernate 只告诉 select 你真正需要执行手头任务的数据,告诉它把结果集转换到你的投影上:

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);
}

Now you don't have a list of Brand s but instead a list of NameIdentityPair s, and NHibernate will have only issued a SQL statement like SELECT b.Identity, b.Name from dbo.Brand b to obtain this projection, as opposed to a massive SQL statement that grabs everything necessary to hydrate a Brand object (eg, SELECT b.Identity, b.Name, b.Description from dbo.brand b left join dbo.vendor v.... ). Now you don't have a list of Brand s but instead a list of NameIdentityPair s, and NHibernate will have only issued a SQL statement like SELECT b.Identity, b.Name from dbo.Brand b to obtain this projection, as opposed to一个庞大的 SQL 声明,其中包含为Brand object 补水所需的一切(例如, SELECT b.Identity, b.Name, b.Description from dbo.brand b left join dbo.vendor v....

Hope this helps.希望这可以帮助。

If you're familiar with SQL, a projection is the SELECT clause of a query, used to select which fields from the available results to return.如果您熟悉 SQL,则投影是查询的SELECT子句,用于 select 哪些字段从可用结果中返回。

For example, assume you have a Person with FirstName , LastName , Address , and Phone fields.例如,假设您有一个包含FirstNameLastNameAddressPhone字段的Person If you want a query to return everything, you can leave off the projection, which is like SELECT * FROM Person in SQL.如果您希望查询返回所有内容,则可以省略投影,例如SELECT * FROM Person in SQL。 If you just want the first and last names, you would create a projection with FirstName and LastName -- which would be SELECT FirstName, LastName FROM Person in SQL terms.如果您只需要名字和姓氏,您可以使用FirstNameLastName创建一个投影——在 SQL 术语中,这将是SELECT FirstName, LastName FROM Person

You can use projections to call sql functions like SUM, COUNT... or select single fields without return an entity.您可以使用投影来调用 sql 函数,如 SUM、COUNT... 或 select 单个字段而不返回实体。

"...Retrieving only properties of an entity or entities, without the overhead of loading the entity itself in a transactional scope. This is sometimes called a report query; it's more correctly called projection." “...仅检索一个或多个实体的属性,而无需在事务性 scope 中加载实体本身的开销。这有时称为报告查询;更正确地称为投影。” [NHibernate in Action] [NHibernate 在行动]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM