[英]JSON.NET and nHibernate, ignore lazy loaded objects when serializing
我有一个包含汽车历史的数据库。 每辆汽车历史都有多个与之相关的图像。 我正在使用 NHibernate 2.2 来设置关系,并且 CarHistory 映射包含一个用于图像的包:
<bag name="Photos" table="DetailPhoto" cascade="all" lazy="true">
<key column="CAR_DETAIL_ID"/>
<one-to-many class="DetailPhoto"/>
</bag>
我有一个 iPad 应用程序,它使用 JSON 与服务器进行通信。 我想将所有汽车历史记录项目加载到 iPad 上的列表中,我不想在加载列表时包含照片,因为它会减慢数据检索速度,这就是我将照片设为懒惰的原因。
当我尝试使用 JsonConvert.SerializeObject 来序列化我的汽车历史列表时,我得到一个延迟初始化异常,这是因为我已经加载了我的对象并关闭了会话,因为我不需要照片并且 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; }
}
所以我的问题是如何在某些情况下而不是在其他情况下检索没有关联照片的 CarHistory 列表?
对于这种情况,您通常希望在“连接的”域对象和序列化格式之间设置一个层。 我通常创建一个数据传输对象,它类似于域模型对象,但通常没有直接关联,而只有 ID 列表。 然后我使用Automapper在数据传输对象和域对象之间进行映射。
默认的合约序列化器尝试序列化所有内容,当它遇到尚未加载的事物时,它无法识别它并尝试序列化它。 这反过来迫使代理尝试加载数据,这会导致性能问题(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
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.