我有ninject在httpRequest上创建一个新会话并在httpRequest结束时关闭它。
现在我通过nhibernate配置文件了解到,我应该总是在事务中包装所有内容甚至查询(读取)。
这导致我的代码中出现了很多错误,因为我会从数据库中检索一个对象,然后对该对象进行修改(主要是将utc时间转换为本地时间)。
这些修改应从不提交到数据库,但由于我现在将所有读取查询包装在一个事务中,当我去从数据库中获取其他内容时需要提交它会执行提交并看到我的对象已更改并保存应将从不保存到数据库的更改。
我会使用逐出,但后来我失去了延迟加载,我通常在实际执行其他激活延迟加载的查询之前转换时间。
我该怎么办?
答案 0 :(得分:2)
NHibernate 3.1在SetReadOnly()
和IQuery
上有ICriteria
方法,可确保查询返回的对象不会被会话保留。
答案 1 :(得分:2)
我建议您将查询结果加载到viewmodel
,然后将viewmodel
的属性转换为当地时间。由于viewmodel
是NOT
附加到nHibernate会话,因此当您的httpRequest结束提交事务时,您将不会更新实体。
viewmodel
实际上是DTO
,可以被描述为数据的flattened model
有关详细信息,请参阅此post(特别是有关automapper的答案)
编辑您的痛点似乎是在执行实际数据显示时。当我遇到这些问题时,我总是使用displayFor
模板。在我看来,我使用了以下几行: -
请注意这是一个人为的例子: -
<h1>Books</h1>
<ul>
@foreach (var book in Model)
{
<li>@book.Name @Html.DisplayFor(x=> book.UnitPrice, "Price")</li>
}
</ul>
然后创建显示模板/Views/Shared/DisplayTemplates/Price.cshtml
@model decimal
<span>£@Model</span>
注意:此视图可以通过帮助程序等执行计算......
这给你带来了不少好处但它确实意味着每个我使用价格的地方都必须使用显示模板。但是我觉得更容易记住,我需要使用显示模板来获取所有价格,日期等,而不是一些可能会错过的命名助手。它总是关于训练/调节自己。
它充满了争论,在一天结束时你需要对自己的工作方式感到满意。但是显示模板对我来说似乎更好。
我还应该指出,我建议您将此视为显示问题,而不是试图提供从数据库中检索数据的kludge。