WPF MVVM 中的 NHibernate 会话
Posted
技术标签:
【中文标题】WPF MVVM 中的 NHibernate 会话【英文标题】:NHibernate Session in WPF MVVM 【发布时间】:2015-09-05 04:36:17 【问题描述】:我正在使用WPF
和NHibernate
,当前使用带有多个线程的单个会话,这会导致与this 链接相同的许多错误。所以现在我必须在完成后立即开始和关闭会话。但问题将是惰性数据。我很困惑如何使用 MVVM 获取它们,如下所示:-
class Product
public virtual string nameget;set;
public virtual Session sessionget;set; // Lazy
public virtual Categories categet;set; //Lazy
public virtual Warehose warehouseget;set; //Lazy
public virtual string NAME
get return Name;
set
Name = value;
OnPropertyChanged("NAME");
public virtual string TerminalName
get return session.terminal.terminalName;
set
session.terminal.terminalName= value;
OnPropertyChanged("TerminalName");
public virtual string CateName
get return session.cate.catename;
set
session.cate.catename= value;
OnPropertyChanged("CateName");
public virtual string UserName
get return session.user.username;
set
session.user.username= value;
OnPropertyChanged("UserName");
class Categories
public virtual string catenameset;get;
class Warehose
public virtual string warenameset;get;
class Session
public virtual People userget;set; //Lazy
public virtual Terminal terminalget;set; //Lazy
//... other properties
Class People
public virtual string usernameset;get;
Class Terminal
public virtual string terminalNameset;get;
我将从列表中的数据库中获取数据并将其作为itemsource
提供给 DataGrid,如下所示
<DataGrid Name="saleDataGrid"
<DataGrid.Columns >
<DataGridTextColumn Binding="Binding NAME" FontSize="12"
CanUserResize="False" Width="70" Header="Code"/>
<DataGridTextColumn Binding="Binding TerminalName" FontSize="12"
Header="Desciption" Width="120" CanUserResize="False"/>
<DataGridTextColumn Binding="Binding CateName" FontSize="12"
Header="Price" Width="50" CanUserResize="False"/>
<DataGridTextColumn Binding="Binding UserName" FontSize="12"
CanUserResize="False" Width="45" Header="QTY"/>
</DataGrid.Columns>
</DataGrid>
因此,当我关闭连接以及DataGrid
显示该时间时,由于会话已关闭,我变得懒惰异常。我不知道我该怎么办。
如果会话关闭,任何人都可以推荐使用 MVVM 获取惰性数据。我不想使用急切加载作为解决方案。
请让我知道您需要更多信息。
谢谢 安吉特
【问题讨论】:
我会避免使用“最佳”一词,因为这会导致问题以基于意见的方式结束。 最好删除 :) 我只是想知道如何解决这个问题 【参考方案1】:在大多数情况下,您有三个选项,它们独立于您使用的 ORM,因为 ORM 的行为非常相似:
让会话/上下文对象与视图模型一样长; 以这种方式构建模型(MVVM 中的“M”),允许您在需要时懒惰地获取数据(每次都创建新的会话/上下文对象)。这会关闭 ORM 的延迟加载,因为模型自己管理延迟加载; 抛弃延迟加载,加载视图模型所需的一切。【讨论】:
在我当前的代码中,我只使用单个会话,我在所有DAO
上都使用了Lock
,但仍然得到There was a problem converting an IDataReader to NDataReader
,这是因为其他一些线程正在读取数据。所以这就是为什么我不能以工作单元的形式开始新的会话。我不明白你的第二点,你能解释一下吗?【参考方案2】:
解决此问题的一种方法是在创建会话工厂时将会话上下文状态设置为“thread_static
”,
如果流畅的 NHibernate
public class NHibernateConfig
public static Configuration Configure()
var cfg = Fluently.Configure()
.Database(...)
.Mappings(...)
.ExposeConfiguration(x => x.SetProperty("current_session_context_class", "thread_static"))
.BuildConfiguration();
return cfg;
如果是 XML 文件
<props>
...
<prop key="hibernate.current_session_context_class ">thread</prop>
...
</props>
这将保持每个线程的会话,您不必处理跨多个线程共享同一会话的问题。
但是长时间保持会话打开并不是一个好主意,因此可能在您启动新视图时,您可以创建一个新会话并在退出视图时关闭它,这样不会影响延迟加载.
【讨论】:
以上是关于WPF MVVM 中的 NHibernate 会话的主要内容,如果未能解决你的问题,请参考以下文章