这是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。
我认为必须有一种更简单的方法。有人能指出我正确的方向吗?
由于
答案 0 :(得分:0)
我认为你走的是正确的道路。但是,由于您使用的是旧版本的NHibernate,因此您将不得不做更多的手动工作。我将获取您的实体的投影,这些实体仅包含您想要加载的列。然后,当UI请求大blob对象时,您将不得不编写另一个查询来获取它们并将它们提供给UI。
答案 1 :(得分:0)
另一个选择是让第二个类(例如SmallDataObject
)具有相同的映射(但没有blob)并将其用于列表。编辑列表项时,您将使用所选列表项的ID加载包含blob的类。
在任何情况下,都无法在创建SessionFactory之后修改映射,因此您无法按需删除映射的属性。