在下面的类中,我想使用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中添加的属性。
我怎样才能实现这一目标或同样的目标?
答案 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功能,例如二级缓存。