如何在运行时强制加载?

时间:2012-04-24 17:56:03

标签: c# nhibernate fluent-nhibernate lazy-loading eager-loading

我正在使用Fluent NHibernate。我在运行时有一个对象,其中包含可能已填充或未填充的惰性集合/属性。我计划序列化该对象,并且在我这样做之前需要填充所有的集合/属性。如何在运行时“急切加载”我的对象?

2 个答案:

答案 0 :(得分:4)

如果您已经在映射中设置了关系,则无需指定如何加入查询,只需使用Fetch(甚至深度提取)来指定要加载的路径:

session.QueryOver<MasterEnt>()
   .Where(x => x.Id == 2)
   .Fetch(x => x.DetailEntList)
   .Eager().List();

答案 1 :(得分:2)

您可以使用ICriteria并通过NHibernate.ICriteria.SetFetchMode(string, NHibernate.FetchMode)操纵负载。

示例:

DetailEnt.cs:

using System;
using System.Collections.Generic;
using System.Text;

namespace FetchTest
{
    public class DetailEnt
    {
        private Int32? id;
        /// <summary>
        /// Entity key
        /// </summary>
        public virtual Int32? Id
        {
            get { return id; }
            set { id = value; }
        }

        private String description;
        /// <summary>
        /// Description
        /// </summary>
        public virtual String Description
        {
            get { return description; }
            set { description = value; }
        }

        private MasterEnt rIMaster;

        /// <summary>
        /// Gets or sets the RI master.
        /// </summary>
        /// <value>
        /// The RI master.
        /// </value>
        public virtual MasterEnt RIMaster
        {
            get { return rIMaster; }
            set { rIMaster = value; }
        }
    }
}

MasterEnt.cs:

using System;
using System.Collections.Generic;
using System.Text;

namespace FetchTest
{
    public class MasterEnt
    {
        private Int32? id;
        /// <summary>
        /// Entity key
        /// </summary>
        public virtual Int32? Id
        {
            get { return id; }
            set { id = value; }
        }

        private String description;
        /// <summary>
        /// Description
        /// </summary>
        public virtual String Description
        {
            get { return description; }
            set { description = value; }
        }

        private ICollection<DetailEnt> detailEntList;
        /// <summary>
        /// <see cref="RIDetailEnt"/> one-to-many relationship.
        /// </summary>
        public virtual ICollection<DetailEnt> DetailEntList
        {
            get { return detailEntList; }
            set { detailEntList = value; }
        }
    }
}

在运行时强制执行加载:

NHibernate.ISession ss = GetSessionFromSomeWhere();

NHibernate.ICriteria crt = ss.CreateCriteria<MasterEnt>();
crt
    .Add(NHibernate.Criterion.Expression.IdEq(17))
    //here is "force eager load at runtime"
    .SetFetchMode("DetailEntList", NHibernate.FetchMode.Join);
MasterEnt mEnt = crt.UniqueResult<MasterEnt>();

在这种情况下,我使用了“hbm”。但逻辑应该是一样的。

EDITED:

使用“NHibernate 2.1.2”和“NHibernate.Linq”

INHibernateQueryable<MasterEnt> nhq = null;
IList<MasterEnt> masterList = null;

nhq = (INHibernateQueryable<MasterEnt>)(
    from master in session.Linq<MasterEnt>()
    where master.Id == 2
    select master);

nhq.Expand("DetailEntList");
masterList = nhq.ToList<MasterEnt>();

来自NHibernate 3的QueryOver<T>Left.JoinQueryOver

IQueryOver<MasterEnt> query = session.QueryOver<MasterEnt>()
    .Left.JoinQueryOver<DetailEnt>(m => m.DetailEntList)
    .Where(m => m.Id == 2);

masterList = query.List<MasterEnt>();

如果使用“FluentNHibernate”或“hbm”,这些查询会以这种方式独立工作。

我为它制作了一些代码,很快我就会发布文件的链接。

编辑2:

我已在q_10303345_1350308.7z上发布了代码(由NUnit运行)。关于“dependencies \ readme.txt”中的依赖关系有解释。 dll依赖项由NuGet加载。