3

我有一个汽车历史数据库。每个汽车历史都有多个与之关联的图像。我正在使用 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 数据返回给客户端,但我不能在我的对象上使用忽略 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 列表?

4

2 回答 2

2

对于这种情况,您通常希望在“连接”域对象和序列化格式之间提供一层。我通常创建一个数据传输对象,它类似于域模型对象,但通常没有直接关联,而是只有 ID 列表。然后我使用Automapper在数据传输对象和域对象之间进行映射。

于 2012-09-25T05:14:55.647 回答
0

默认的 contract-serializer 尝试序列化所有内容,当它遇到尚未加载的事物时,它无法识别它并尝试对其进行序列化。这反过来又迫使代理尝试加载数据,这会导致性能问题(1 + n + n^2 + .. 查询)或直接抛出异常(当会话已经关闭时) - 这就是您在第一名。

使用自定义的合同解析器,您将能够指示序列化程序不序列化未加载的集合和属性。或者更好地抛出一个异常,或者记录它,无论你想要什么。

查看类似的问题:NHibernate Proxies (NH 3.3.2.4000) 的 JSON.Net Serialization - 您可以在那里找到自定义 ContractResolver 的示例。

但是,由于您的问题不同,它并不完全满足您的需求,因此在编写自己的 ContractResolver 时,您应该在其中过滤要序列化的属性,例如:

var propertyInfo = (PropertyInfo)member;
var value = propertyInfo.GetValue(target);
var shouldSerialize = NH.NHibernateUtil.IsInitialized(value);

false当属性包含已代理但尚未加载的集合或对象引用时产生。

于 2017-11-02T10:05:14.507 回答