从所有表中获取数据,而不是使用 HQL 查询从一个表中获取数据,而 HQL 查询应该只获取 1 个表的数据
我在数据库中创建了 3 个表并将数据放入其中。这 3 个表都有外键将它们连接在一起。下面是表类和映射。当我运行最后列出的查询时,我得到 IList<>对象的数据,并且它们具有所有 3 个表中的数据。但是,我的 HQL 查询仅来自最顶层的表。我怎样才能只取回最上面的表的结果?
这些是我的课程:
public class Technology
{
public virtual int Id { get; private set; }
public virtual string Name { get; set; }
public virtual int SortOrder { get; set; }
public virtual string Abbreviation { get; set; }
public virtual IList<TechnologyDescription> TechnologyDescriptions { get; private set; }
public Technology()
{
TechnologyDescriptions = new List<TechnologyDescription>();
}
public virtual void AddTechnologyDescription(TechnologyDescription technologyDescription)
{
technologyDescription.Technology = this;
TechnologyDescriptions.Add(technologyDescription);
}
}
public class TechnologyDescription
{
public virtual int Id { get; private set; }
public virtual Technology Technology { get; set; }
public virtual string Description { get; set; }
public virtual DescriptionType DescriptionType { get; set; }
}
public class DescriptionType
{
public virtual int Id {get; private set;}
public virtual string Type { get; set; }
}
These are my mapping objects:
public class TechnologyMap : ClassMap<Technology>
{
public TechnologyMap()
{
Id(x => x.Id);
Map(x => x.Name);
Map(x => x.SortOrder);
Map(x => x.Abbreviation);
HasMany(x => x.TechnologyDescriptions)
.Inverse()
.Cascade.All();
}
}
public class TechnologyDescriptionMap : ClassMap<TechnologyDescription>
{
public TechnologyDescriptionMap()
{
Id(x => x.Id);
References(x => x.Technology);
Map(x => x.Description);
References(x => x.DescriptionType);
}
}
public class DescriptionTypeMap : ClassMap<DescriptionType>
{
public DescriptionTypeMap()
{
Id(x => x.Id);
Map(x => x.Type);
}
}
这是我的 HQL 代码:
IQuery q = session.CreateQuery("from Technology T");
IList technologies = q.List();
I have created 3 tables in my database and put data into them. The 3 tables all have foreign keys joining them together. Below are the table classes and there mappings. When I run the query listed at the end I get IList<> of the objects and they have the data from all 3 tables. However, my HQL query is only from the top most table. How can I get back just the results from the top most table?
These are my classes:
public class Technology
{
public virtual int Id { get; private set; }
public virtual string Name { get; set; }
public virtual int SortOrder { get; set; }
public virtual string Abbreviation { get; set; }
public virtual IList<TechnologyDescription> TechnologyDescriptions { get; private set; }
public Technology()
{
TechnologyDescriptions = new List<TechnologyDescription>();
}
public virtual void AddTechnologyDescription(TechnologyDescription technologyDescription)
{
technologyDescription.Technology = this;
TechnologyDescriptions.Add(technologyDescription);
}
}
public class TechnologyDescription
{
public virtual int Id { get; private set; }
public virtual Technology Technology { get; set; }
public virtual string Description { get; set; }
public virtual DescriptionType DescriptionType { get; set; }
}
public class DescriptionType
{
public virtual int Id {get; private set;}
public virtual string Type { get; set; }
}
These are my mapping objects:
public class TechnologyMap : ClassMap<Technology>
{
public TechnologyMap()
{
Id(x => x.Id);
Map(x => x.Name);
Map(x => x.SortOrder);
Map(x => x.Abbreviation);
HasMany(x => x.TechnologyDescriptions)
.Inverse()
.Cascade.All();
}
}
public class TechnologyDescriptionMap : ClassMap<TechnologyDescription>
{
public TechnologyDescriptionMap()
{
Id(x => x.Id);
References(x => x.Technology);
Map(x => x.Description);
References(x => x.DescriptionType);
}
}
public class DescriptionTypeMap : ClassMap<DescriptionType>
{
public DescriptionTypeMap()
{
Id(x => x.Id);
Map(x => x.Type);
}
}
And this is my HQL code:
IQuery q = session.CreateQuery("from Technology T");
IList technologies = q.List();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不知道是否可以使用 HQL,但是使用 NHibernate 的 Criteria API,您可以这样做:
但是,这可能并不是您真正想要的。现在不会获取 TechnologyDescriptions,但是一旦您访问它们(即:第一次调用 TechnologyDescriptions 属性时)就会获取它们。
使用 NHibernate 时,您不应该考虑“数据”。相反,您应该从“实体”的角度来思考。
检索实体时,您希望完全检索实体(直接或以惰性方式)。部分检索实体是不可能的,这是很明显的;
当您尝试保存已部分检索的实体时,NHibernate 应该如何处理该实体?
我脑子里还浮现出另外一件事:
我想您想检索技术,但没有任何相关内容,因为您想在概述或类似的内容中显示它们?
在这种情况下,您应该看看“转换”。
例如,您可以创建一个名为
TechnologyView
的附加类,如下所示:完成此操作后,您必须通知 NHibernate 该类的存在。
例如,您可以通过在 hbm.xml 文件中导入类来完成此操作。 (我不知道如何使用 Fluent 来做到这一点)。
之后,您可以创建一个查询(使用 HQL 或 Criteria)来检索
TechnologyView
实例。 NHibernate 足够智能,可以生成高性能的 SQL 查询。使用 HQL:
使用标准:
I don't know if it is possible using HQL, but using NHibernate's Criteria API, you can do this:
However, this is probably not really what you want. The TechnologyDescriptions won't be fetched right now, but they will be fetched once you access them (that is: the first time you call the TechnologyDescriptions property).
When working with NHibernate, you shouldn't think in terms of 'data'. Rather, you should think in terms of 'entities'.
When retrieving an entity, you want to retrieve the entity entirly (directly, or in a lazy fashion). It is not possible to retrieve an entity partially, and this is quite obvious;
What should NHibernate do with an entity that you've retrieved partially, when you try to save that entity ?
Something else that pops in my mind:
I suppose you want to retrieve the Technologies, and nothing related because you want to display them in an overview or something like that ?
In such case, you should take a look at 'Transformations'.
You could for instance create an additional class which is called
TechnologyView
, which looks like this:Once you've done this, you must inform NHibernate about the existance of this class.
You do this by Importing the class in an hbm.xml file for instance . (I do not know how to do it using Fluent).
After that, you can create a query (using HQL or Criteria) which retrieves
TechnologyView
instances. NHibernate is smart enough to generate a performant SQL query.using HQL:
using Criteria:
我认为您正在寻找的是延迟加载的 TechnologyDescriptions。这样,只有在访问描述时才会从数据库加载描述(NHibernate 将发出第二个数据库查询。请注意,这在某些情况下可能会导致 N+1 选择,并且根据使用情况,您可能更喜欢一次性查询。 )
NHibernate xml 映射默认为延迟加载集合。过去,Fluent NHibernate 似乎没有相同的默认值。您需要将
.LazyLoad()
添加到映射中。最近看起来延迟加载已经成为默认的流畅映射:收藏?
Fluent NHibernate 的默认行为是延迟加载 HasMany
I think what you're looking for is for the TechnologyDescriptions to be lazy loaded. That way the descriptions get loaded from the database only when they are accessed (NHibernate will issue a second db query. Note that this can lead to N+1 selects in some situations and you might prefer the all at once query depending on the usage.)
By NHibernate xml mappings default to lazy loading of collections. In the past it seems that the Fluent NHibernate did not have the same default. You need to add
.LazyLoad()
to the mapping.Recently it looks like lazy loading has become the default fluent mapping:
Is the default behavior with Fluent NHibernate to lazy load HasMany<T> collections?