如何确保使用(流畅的)NHibernate 延迟加载对象?
我有一个在服务器端使用 Fluent NHibernate 来配置数据库的应用程序。 Fluent 默认使用延迟加载,但我明确禁用了它,因为这在将对象发送到客户端时给我带来了问题。显然,客户端无法延迟加载对象,因为它无权访问数据库。
现在,我尝试为数据模型的某些部分重新启用延迟加载,因为有些部分我只想将顶级对象返回给客户端。然而,它们似乎并不是延迟加载的。为什么?!
我禁用 LazyLoading 的方法是在映射对象中以及映射中的引用上添加 Not.LazyLoading()
。现在删除这个似乎没有效果。调试我看到所有引用的对象,并且我还在客户端获取它们。但是,NHibernateUtil.IsInitialized(myObjectFromDb.SomeReference)
同时正确地显示 false。所以;如何确保对象是延迟加载的;将缺少引用的对象返回给客户端?有什么想法我可能会做错吗?
我有几个类(非常简单的示例..):
public class Customer
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual IList<Order> Orders { get; set; }
}
public class Order
{
public virtual int Id { get; set; }
public virtual IList<Item> Items { get; set; }
}
public class Item
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
简单映射 - 使用默认的 LazyLoading:
public class CustomerMapping : ClassMap<Customer>
{
public CustomerMapping()
{
Id(c => c.Id);
Map(c => c.Name);
HasMany(c => c.Orders);
}
}
public class OrderMapping : ClassMap<Order>
{
public OrderMapping()
{
Id(c => c.Id);
HasMany(c => c.Items);
}
}
public class ItemMapping : ClassMap<Item>
{
public ItemMapping()
{
Id(c => c.Id);
Map(c => c.Name);
}
}
我使用 Session.Load
直接获取它 - 通过我的返回结果直接 REST 服务,无需访问对象,以便加载惰性引用。加载之后以及返回到服务器端的对象上都会加载引用。我怎样才能防止这种情况发生?
I have an application using Fluent NHibernate on the server side to configure the database. Fluent uses Lazyloading as default, but I explicitly disabled this as this gave me problems when sending the objects to the client side. Obviously the client can't load the objects lazily as it doesn't have access to the database.
Now I try reenabling Lazyloading for parts of my datamodel as there are some parts where I only want to return toplevel objects to the client. However, they don't seem to be Lazyloaded. Why?!
What I did to disable LazyLoading was adding Not.LazyLoading()
in the mapping object, and on references in the mapping. Now removing this doesn't seem to have effect. Debugging I see all the referenced objects, and I also get them all on the client side. However, the NHibernateUtil.IsInitialized(myObjectFromDb.SomeReference)
correctly says false at the same time. So; how do I ensure that the objects are lazy-loaded; getting a object missing its references back to the client? Any ideas what I might got wrong?
I have a few classes (very simplified example..):
public class Customer
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual IList<Order> Orders { get; set; }
}
public class Order
{
public virtual int Id { get; set; }
public virtual IList<Item> Items { get; set; }
}
public class Item
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
Simple mappings - using default LazyLoading:
public class CustomerMapping : ClassMap<Customer>
{
public CustomerMapping()
{
Id(c => c.Id);
Map(c => c.Name);
HasMany(c => c.Orders);
}
}
public class OrderMapping : ClassMap<Order>
{
public OrderMapping()
{
Id(c => c.Id);
HasMany(c => c.Items);
}
}
public class ItemMapping : ClassMap<Item>
{
public ItemMapping()
{
Id(c => c.Id);
Map(c => c.Name);
}
}
And I fetch it straight forward with a Session.Load<Customer>(id)
- returning the result over my REST service directly without accessing the object such that the lazy references are loaded. Both right after the Load and on the object returned to the server side the references are loaded. How can I prevent this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
做了更多的研究和测试。事实证明,延迟加载就像预期的一样简单。这是映射中的默认行为,因此不提及任何内容实际上会导致对象被延迟加载。
问题是:它们什么时候加载?好吧 - 如果它们是延迟加载的,那么只要有人需要它们,它们就会在会话范围内加载。所以;在调试模式下检查对象以检查它是否已加载实际上会触发对象的加载 - 延迟。因此检查员将显示已加载的参考,并且一切看起来都很好。
我的情况的问题是我提到的“在会话范围内”。我有客户端和服务器端。服务器提供 REST 服务,客户端使用 HttpClient 调用这些服务。在服务器上,数据将被包装在 XML 中,然后返回。就我而言,当我返回结果时,会话仍然存在 - 这意味着数据的包装将在需要时延迟加载引用。这样我就得到了所有的引用,并将完整的对象返回给客户端。
所以;为了确保使用 Fluent NHibernate 进行延迟加载,只需不要显式设置任何内容,然后注意您是否实际以任何方式使用对象引用,因为这将导致它们被加载。
Did some more research and testing. Lazy Loading turns out to be as simple as expected. This is the default behavior in the mappings, so not saying anything about it will actually cause the objects to be Lazy Loaded.
The question is: When are they loaded? Well - if they are Lazy Loaded they will be loaded whenever anyone needs them - within the scope of the session. So; inspecting the object in Debug-mode to check if it is loaded will in fact trigger loading of the object - lazily. So the inspector will show the references as loaded, and everything will look fine.
The problem in my case was what I mentioned about "within the session scope". I have a client and server side. The server provides REST services, and the client calls these using an HttpClient. On the server the data will be wrapped in XML, and then returned. In my case the session still lives when I return the result - meaning that the wrapping of the data will load the references lazily - when needed. So I get all the references, and the complete object is returned to the client.
So; to ensure Lazy Loading with Fluent NHibernate just don't set anything explicitly, and then be aware if you actually use the objects references in any way as this will cause them to be loaded.