保持NHibernate加载某些字段

时间:2011-03-30 14:04:39

标签: nhibernate lazy-loading

这是My earlier question on lazy loading properties的后续问题。由于应用程序是对相当大的企业中的生产应用程序的增强,并且它当前使用NHib 1.2运行,因此不会发生升级到版本3,因此在3.0中使用Lazy Properties的建议答案对我来说不起作用

总结一下这个问题,我有一个带有2个表的简单数据库。一个人有十几个简单的字段,加上与第二个表的一对多关系作为子表。其中两个字段是非常大的blob(每个几兆字节),我想,有效地,懒惰加载它们。此表有大约10条记录,它们在启动时填充网格,但只有在选择任何行时才需要访问大块。

对象结构如下所示:

[Serializable]
[Class(Schema = "dbo", Lazy = false)]
public class DataObject
{
    [Id(-2, Name = "Identity", Column="Id")]
    [Generator(-1, Class="native")]
    public virtual long Identity { get; set;}
    [Property]
    public string FieldA { get; set;}
    [Property]
    public byte[] LongBlob {get; set;}
    [Property]
    public string VeryLongString { get; set;}
    [Bag(-2, Cascade=CascadeStyle.All, Lazy= false, Inverse=true)]
    [Key(-1, Column="ParentId")]
    [OneToMany(0, ClassType=typeof(DataObjectChild))]
    public IList<DataObjectChild> ChildObjects { get; set;}
}

目前,通过简单的查询访问该表:

          objectList = (List<DataObject>) Session.CreateQuery("from DataObject").List<DataObject>();

它可以处理所有事情,包括加载子对象。

我想要的是一个完全相同的查询,除了选择包含除两个blob之外的所有内容的DataObject属性列表。然后我可以添加自定义属性Getter,它们会在访问时加载这些属性。

到目前为止,我还没有成功。

我尝试过的事情:

a)使用SELECT列表构造HQL查询。 它看起来像这样:

objectList = (List<DataObject>) Session.CreateQuery(
    "SELECT new DataObject " +
    "(obj.Identity, obj.FieldA) " +    
    "from DataObject as obj")

虽然我必须在DataObject中添加一个构造函数,然后从我选择的字段构造它,这很麻烦。但是它没有加载和扩展子对象列表,我无法弄清楚如何轻松地做到这一点(并且我真的不想 - 我想告诉NHib这样做。)

b)从对象定义中的两个字段中删除[Property]属性。这使得NHibernate.Mapping.Attributes不会映射这些字段,因此它们不会包含在查询中,但是我根本无法从NHib访问它们,包括在我去保存新的或者修改了DataObject。

我认为必须有一种更简单的方法。有人能指出我正确的方向吗?

由于

2 个答案:

答案 0 :(得分:0)

我认为你走的是正确的道路。但是,由于您使用的是旧版本的NHibernate,因此您将不得不做更多的手动工作。我将获取您的实体的投影,这些实体仅包含您想要加载的列。然后,当UI请求大blob对象时,您将不得不编写另一个查询来获取它们并将它们提供给UI。

答案 1 :(得分:0)

另一个选择是让第二个类(例如SmallDataObject)具有相同的映射(但没有blob)并将其用于列表。编辑列表项时,您将使用所选列表项的ID加载包含blob的类。

在任何情况下,都无法在创建SessionFactory之后修改映射,因此您无法按需删除映射的属性。