获取我的ManyToOne对象的唯一ID

时间:2011-08-01 15:42:55

标签: c# nhibernate

我有这个映射:

[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

但我不知道它是否错了,或者我是否应该采用不同的方式。

3 个答案:

答案 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并开始痛苦。