我有一个Car Histories数据库。每个汽车历史记录都有多个与之相关的图像。我使用NHibernate 2.2建立关系,CarHistory映射包含图像包:
<bag name="Photos" table="DetailPhoto" cascade="all" lazy="true">
<key column="CAR_DETAIL_ID"/>
<one-to-many class="DetailPhoto"/>
</bag>
我有一个使用JSON与服务器通信的iPad应用程序。我想将所有汽车历史项目加载到iPad上的列表中,我不想在加载列表时包含照片,因为这会减慢数据检索速度,这就是我使照片变得懒惰的原因。
当我尝试使用JsonConvert.SerializeObject来序列化我的Car Histories列表时,我得到了一个懒惰的初始化异常,因为我已经加载了我的对象并关闭了会话因为我不需要照片并且JsonSerializer正在触摸对象上的所有属性。
我想在没有照片的情况下将Json数据返回给客户端但我不能在我的对象上使用ignore JsonProperty,因为我想在其他情况下加载此集合。
我试过这个但它只是做了同样的事情给了我懒惰的初始化异常: http://www.royjacobs.org/2011/07/27/using-json-net-to-serialize-proxied-nhibernate-objects/
这是我的CarHistory(CarDetail)课程
public class CarDetail
{
[JsonProperty("id")]
public virtual int Id { get; set; }
[JsonProperty("carId")]
public virtual int CarId { get; set; }
[JsonProperty("date")]
public virtual DateTime ? Date { get; set; }
[JsonProperty("details")]
public virtual string Details { get; set; }
[JsonProperty("photos")]
public virtual IList<DetailPhoto> Photos { get; set; }
}
所以我的问题是如何在某些情况下检索没有相关照片的CarHistories列表而不是其他情况?
答案 0 :(得分:1)
对于这种情况,您需要在“连接”域对象和序列化格式之间创建一个图层。我通常创建一个数据传输对象,它类似于域模型对象,但通常没有直接关联,而只是有ID列表。然后我使用Automapper在数据传输对象和域对象之间进行映射。
答案 1 :(得分:0)
默认的contract-serializer尝试序列化所有内容,当它遇到尚未加载的东西时,它无法识别它并尝试序列化它。这反过来迫使代理尝试加载数据,这会导致性能问题(1 + n + n ^ 2 + ..查询)或者直接抛出异常(当会话已经关闭时) - 这就是你在第一名。
使用自定义合约解析程序,您将能够指示序列化程序不序列化未加载的集合和属性。或者抛出更好的异常,或者记录它,无论你想要什么。
查看类似问题:JSON.Net Serialization of NHibernate Proxies (NH 3.3.2.4000) - 您可以找到自定义ContractResolver的示例。
虽然您的需求并不完整,因为您的问题不同,因此在编写自己的ContractResolver时,您应该在其中过滤要序列化的属性,例如:
var propertyInfo = (PropertyInfo)member;
var value = propertyInfo.GetValue(target);
var shouldSerialize = NH.NHibernateUtil.IsInitialized(value);
当属性包含已代理但尚未加载的集合或对象引用时,会生成false
。