我刚从NHibernate开始,使用fluent NHibernate创建了映射,如下所示:
public class CustomerMap : ClassMap<Customer>
{
public CustomerMap()
{
Id(x => x._id, "Id");
Map(x => x._KdNr, "KdNr");
Map(x => x._Name, "Name");
HasMany(x => x._Contact)
.Table("Contacts")
.KeyColumn("FKCustomerID")
.LazyLoad();
}
}
public class ContactMap : ClassMap<Contact>
{
public ContactMap()
{
Id(x => x._id, "Id");
Map(x => x._Name, "Name");
}
}保存新记录的工作还包括:
public static void AddCustomer(Customer cust)
{
using (var session = SessionFactory.Instance.OpenSession())
{
session.Save(cust);
session.Save(cust._Contact);
session.Flush();
}
}然后,我尝试使用以下方法选择添加的客户:
using (var session = SessionFactory.Instance.OpenSession())
{
try
{
var v = session.CreateQuery("from Customer").List<Customers>();
return (List<Customer>)v;
}
catch
{
session.Close();
throw;
}
finally
{
session.Disconnect();
}
}
}客户也可以很好地加载,但是内部的联系人没有引用以下错误:
Initializingfnh.DataModel.Customer#d2f2d1c5-7d9e-4f77-8b4f-9e200088187b-failed延迟初始化角色集合: fnh.DataModel.Kunde._Contact,没有关闭任何会话或会话
但是我不明白错误是从哪里来的,因为会话在执行HQL错误后关闭了.
发布于 2010-10-31 16:05:33
问题是这些联系人装得很懒。在初始查询中,集合不会从数据库中获取。我假设您是直接将对象传递到视图,而不是使用视图模型吗?你有几个选择,每个选项都有它们的缺点。
更新回应评论:
让集合延迟加载仍然有很大的好处。当然,在这种情况下,您不会从客户对象上延迟加载的联系人中获益,因为您需要使用它们。但在另一种情况下,您可能只需要客户名称和Id -您可以放心,这不会产生一个大查询与联接等。
要利用视图中的Open,您不必显式地将会话传递给视图,而是像以前一样传递对象,但让会话保持打开状态-- NH将在尝试访问联系人集合时自动生成新的查询。(这是因为customer对象仍然“连接”在幕后的开放会话)。这里唯一的区别是,您需要关闭会话,而不是在控制器中(在控制器中,它目前正显式地使用.close()关闭,或者隐式地使用‘The’)。关于会议在何处开幕和闭幕的问题,有几种不同的做法:
对于最后两个页面,您可能会想‘但这将意味着为每个页面请求创建一个会话!’--您是对的,但是到底有多少页不会转到DB呢?此外,一旦创建了会话工厂,会话创建也是轻量级的。
当然,许多人不喜欢视图中的开放会话,因为您无法控制纯粹在控制器中生成哪些查询--视图触发了许多查询,这会导致无法预测的性能。
3与2有很大的不同,因为在不需要延迟加载的集合的情况下,它不会从DB中获取。例如,在本例中,您可能使用完整的对象图复制到ViewModel,但在另一种情况下,您可能使用只具有客户名称和Id的ViewModel --在本例中,联系人集合的联接不会被不必要地执行。在我看来,3是正确的做事方式--但你最终会创建更多的对象(因为视图对象)。
https://stackoverflow.com/questions/4062305
复制相似问题