C# 仅获取my Manytone对象的id

C# 仅获取my Manytone对象的id,c#,nhibernate,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 = "ba

我有以下映射:

[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; }
}
我知道我能行

Session.Get1.Bar.Id但是,它加载Bar对象,如果它是一个非常重的对象,我的简单查询,它只需要foo表中的某些内容,那么它的速度非常慢。我该怎么做

我考虑过添加这样的属性

[Property(Column = "bar_id", NotNull = true)]
public virtual long BarId { get; set; }
但是我不知道它是否错了,或者我是否应该以不同的方式来处理它。

NHibernate支持。检查这是否解决了您的问题

尝试使用Session.Loadid

NHibernate应该足够聪明,意识到它不需要加载Bar并生成只包含其ID的代理版本。它只会在您访问其另一个属性时加载Bar


但是,会话.Get使用缓存。但是,如果您要将其更改为使用Session.Loadid,您应该会看到这种行为。

最后,我们这样做:

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,痛苦就开始了。

是的,我知道延迟加载,但我无法在第二个Bar对象中改变这一点。事实上,我只是不理解我的NHibernate强迫我加载对象栏,因为我的第一个对象Foo中有一些东西…这不是延迟加载,而是延迟属性。。。如果有大量字段而不是映射,则可以将其标记为懒惰。去看看ayende的文章吧。对不起,我知道这篇文章,我在代码的其他地方也用过。我的问题是,我无法更改属性以使属性变为惰性,因为它可能会破坏其他代码。你是说.Loadid吗?因为这里我不知道Bar的id,这就是我想要的,如果我执行Session.Loadid.Bar.id,你认为它不会加载Bar对象,而只加载Bar.id属性吗?我很确定。检查返回的对象的实际类型。它们应该是生成的代理类型。好吧,现在,如果我需要加载一堆Foo对象,使用Session.CreateCriteria.List,我会被这样一个事实所困扰:Bar不是延迟加载的:/I我无法更改此行为:/I不理解。默认情况下,所有关系都应该是延迟加载的。
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>();