0

我有一个问题我已经尝试解决了一段时间。

场景如下

该人将在数据库中插入一个新实体。

要开始插入,我需要从 xml 文件进行昂贵的转换以填充一些基本属性。

我想在之前处理这个 xml 并将已经转换为 o 对象的对象存储在一些缺少的缓存中。

之后,填充这个对象的其他属性的过程非常耗时,我希望这个人可以在中间停下来然后结束它。但是,由于插入此对象时在数据库中进行了一些验证,因此我无法将此对象不完整地保存在数据库中。

我整理的解决方案涉及在人停止填充对象时序列化对象,即使它还没有完成,而不是当人回来继续填充时,我会反序列化对象,以便人可以继续。

问题是,当我尝试序列化这个对象时,nihibernate 由于延迟加载而序列化了几乎整个数据库,并且我得到了 stackoverlow 错误(哈哈,在这里说这个错误很有趣,哈哈)。

有谁知道我应该怎么做?

我所做的一件事是将对象保留在缓存中(不知道 /net 4 缓存如何对其进行序列化但接缝工作)但是每次我检索对象时它都会丢失一半的子对象,而且总是正好一半这些孩子 ....

如果是实时的,我有一个包含 20 个项目的订单,如果我尝试从缓存中取回它,它将返回 10 个项目,如果我再次尝试检索它,我将得到只有 5 个项目的订单。

有谁知道如何解决这个问题?

已经在那里尝试了

NHibernate 使用 WCF 序列化延迟加载的实体

将 nHibernate 查询序列化为 JSON

4

1 回答 1

1

一种方法是先投影您想要的,然后将结果序列化为 DTO。

但是,这样做会遇到一个问题,即创建具有大量 setter/getter 的 DTO。创建一个简单的匿名类型并将其序列化不是更容易吗?我写了一篇博客文章来解释这一点。

//first create our anonymous type DTO
var dto = new { 
    Id = 0L, 
    Source = string.Empty, 
    Destination = string.Empty, 
    Is301 = false
};

//notice the ListAs(dto) extension method
var model = Session.QueryOver<CmsRedirect>()
  .SelectList(s => s
    .Select(x => x.Id).WithAlias(() => dto.Id)
    .Select(x => x.Source).WithAlias(() => dto.Source)
    .Select(x => x.Destination).WithAlias(() => dto.Destination)
    .Select(x => x.Do301).WithAlias(() => dto.Is301)
  )
  .Take(take).Skip(page * pageSize)
  .ListAs(dto);

return Json(new { Total = total, List = model }, 
    JsonRequestBehavior.AllowGet);

ListAs 是一种简单的(ish)扩展方法。(归功于菲利普·金斯基)

public static class NHibernateExtensions {
  public static IList<TRes> ListAs<TRes>(
      this IQueryOver qry, TRes resultByExample) {

    var ctor = typeof(TRes).GetConstructors().First();

    return qry.UnderlyingCriteria
      .SetResultTransformer(
        Transformers.AliasToBeanConstructor(
         (ConstructorInfo) ctor)
        ).List<TRes>();
  }
}

但请注意,在我的示例中,我不会序列化子集合,因此您可能需要自己手动处理。

于 2012-08-26T10:11:36.273 回答