NHibernate Session.Query <t>()。FetchMany

时间:2017-03-30 13:21:58

标签: c#-4.0 nhibernate lambda linq-to-nhibernate queryover

在下面的类中,我想使用session.Query()。FetchMany来加载子集合OrderDetailList。

实体:

 public class Order
 {
    public Order()
    {
        OrderDetailList = new HashSet<OrderDetails>();
    }

    public virtual int Id { get; protected internal set; }
    public virtual string Description { get; set; }

    public virtual ISet<OrderDetails> OrderDetailList { get;set; }
 }

数据存储库:

 public IList<T> All()
 {
        IList<T> result;
        using (var _session = _factory.OpenSession())
        {
            result = _session.Query<T>().ToList();
        }
        return result;
}

使用上面的All方法,返回的子集合只是代理对象,当会话关闭时会导致错误。 所以我想把方法设为:

public IList<T> All()
{
        IList<T> result;
        using (var _session = _factory.OpenSession())
        {
            //result = _session.Query<Order>().FetchMany(x=>x.OrderDetailList).ToList();

            //Required Statement: Above statement must be like
            result = _session.Query<T>().FetchMany(x=>x.[Some children property Generic type List in type T]).ToList();

        }
        return result;
}

但是在这种情况下我的方法是泛型类型,因此我需要在类型T中读取我需要在FetchMany中添加的属性。

我怎样才能实现这一目标或同样的目标?

1 个答案:

答案 0 :(得分:0)

您需要将您的提取作为参数传送。

public IList<T> All<TFetched>(Expression<Func<T, IEnumerable<TFetched>>> fetchmany)
{
        IList<T> result;
        using (var _session = _factory.OpenSession())
        {
            //result = _session.Query<Order>().FetchMany(x=>x.OrderDetailList).ToList();

            var query = _session.Query<T>();
            if (fetchMany != null)
            {
                query = query.FetchMany(fetchmany);
            }
            result = query.ToList();
        }
        return result;
}

然后你可以打电话:

orderRepository.All(x=>x.OrderDetailList);

这可以解决你的直接麻烦。

备注:
但请记住,您当前的设计似乎是值得商榷的。会议应该是短暂的,但不是那个时候。会话应跨越一个工作单元,通常包括许多数据访问或写入。例如,它可能跨越桌面应用程序中用户触发事件的整个处理,或Web应用程序中http请求的处理。

如果您启用batch loading延迟加载以避免N + 1加载,这可能会使您使用延迟加载而不是急切提取,当然,如果在会话结束后不再使用实体。 (例如,这可以通过在关闭会话之前将所需数据提取到视图模型中来实现。)

此外,您应该使用显式事务。不这样做会为每个请求创建隐式事务,这对性能不利。 (但是,对于您当前的设计,显式事务当前不会改变任何内容。)不使用显式事务可能会禁用某些NHibernate功能,例如二级缓存。