我有这个映射:
[Class(Table = "foo", Name = "Foo")]
public class Foo
{
[Id(0, TypeType = typeof(long), Name = "Id", Column = "id")]
[Generator(1, Class = "native")]
public virtual long Id { get; set; }
[ManyToOne(Class = "Bar", Column = "bar_id", NotNull = true)]
public virtual Bar Bar { get; set; }
}
[Class(Table = "bar", Name = "Bar")]
public class Bar
{
[Id(0, TypeType = typeof(long), Name = "Id", Column = "id")]
[Generator(1, Class = "native")]
public virtual long Id { get; set; }
[Bag(0, Inverse = true, Table = "foo", Cascade = "save-update")]
[Key(1, Column = "bar_id", ForeignKey = "fk_foo_bar_id")]
[OneToMany(2, Class = "Foo")]
public virtual IList<Foo> Foos { get; set; }
}
我想做SQL查询:
SELECT bar_id FROM foo f WHERE f.id = 1
我知道我能做到
Session.Get<Foo>(1).Bar.Id
然而,它会加载Bar
对象,如果它是一个非常 HEAVY 对象,我的简单查询只需要{{1}内的内容表非常慢。我该怎么办?
我考虑过添加像这样的属性
foo
但我不知道它是否错了,或者我是否应该采用不同的方式。
答案 0 :(得分:0)
NHibernate支持lazy properties。检查是否能解决您的问题。
答案 1 :(得分:0)
尝试使用Session.Load<Foo>(id)
。
NHibernate应该足够智能,以实现它不需要加载Bar
并生成仅包含其ID的代理版本。如果你访问了另一个属性,它只会加载Bar。
然而Session.Get()
does not do this因为它使用了缓存。但是,如果您要将其更改为使用Session.Load<Foo>(id)
,则应该会看到此行为。
答案 2 :(得分:0)
最后我们这样做了:
public class FooToBarResult
{
public string FooId { get; set; }
public int BarId { get; set; }
}
IList<BlockToComponentResult> result = session
.CreateSQLQuery(@"SELECT bar_id as BarId, id as FooId FROM `foo`")
.SetResultTransformer(Transformers.AliasToBean<FooToBarResult>())
.List<FooToBarResult>();
我的结论是NHibernate很酷,如果你只做他们想要你做的事情,但是只要你遇到一些性能问题并想要优化查询,就需要回到SQL并开始痛苦。