每个对话的例子NHibernate的会议例子、会议、NHibernate

2023-09-04 04:17:23 作者:一人走,不回头

您好可以的一些优点与NHibernate给我示例实现每个对话或unhaddins实施NHibernate的会议? 或解释如何做到这一点。 诚挚的问候 Endiss

Hello can some pros with nhibernate give me example implementation of Nhibernate session per conversation or unhaddins implementation? Or explain how to do that. Best regards Endiss

推荐答案

我与NHibernate工作4年。 previously我与开放式的session-per-操作反模式。这些对象总是分离。因此,要坚持下去,我不得不重新安装它们或它们的值复制到连接的对象。这将导致code和许多懒初始化exeption。

I work with NHibernate to 4 years. Previously I worked with the "open-session-per-operation" antipattern. The objects were always detached. So, to persist, I had to reattach them or copy their values to attached objects. This causes many lines of code and many "lazy initialization exeption".

近日,笔者研究了的会话模式,然后我做了一个执行过的Spring.Net 的基础设施。实施已提交jira.springsource在的问题SPRNET-1431(解决方法的对话范围和的session-per-谈话)。

Recently, I studied the "Conversation pattern" and I did an implementation over the the "Spring.Net" infrastructure. The implementation was submitted to "jira.springsource" at the Issue SPRNET-1431 (Workaround for 'conversation scope' and "session-per-conversation").

我再没示例应用程序,但如果你有兴趣,我可以做到这一点。

I made no "sample application", but if you're interested I can do that.

Hailton

我prepared示例应用程序,并张贴在 SPRNET-1431的解决方法对话范围和的session-per-谈话作为文件Spring.Conversation.example.7z。

I prepared the sample application and posted in SPRNET-1431 Workaround for 'conversation scope' and "session-per-conversation" as the file "Spring.Conversation.example.7z".

下面,我写了解释澄清(或没有)我做了什么。

Below, I wrote explanations to clarify (or not) what I did.

这示例应用程序是包含在该版1.3.0Spring.Data.NHibernate.NorthwindSpring.NET的修改使用会话。   目前,Spring.Net有没有的谈话范围,也不是实现扩展持久化上下文(每个对话战略会议)。

This "sample application" is a modification of "Spring.Data.NHibernate.Northwind" contained in the version "1.3.0" of "Spring.NET" to use Conversation. Currently, the "Spring.Net" has no "conversation scope" nor implements the concept of "Extended Persistence Context" ("session per conversation strategy").

在此示例应用程序的目的是演示:

In this Sample Application the objective is demonstrate:

如何保持在对话范围一个模仿对象的实例。显示在 EX pression =@(convCustomer)['CustomerEditController']。 如何享受扩展持久化上下文。 延迟加载错误不会再发生了,并一再呼吁, ISession.Get 来了相同的记录不会导致数据库多次访问,更有效地使用的NHibernate缓存。在CustomerList.aspx的修改说明这一点。为了验证会话的有效性,对APP_ code \ ConversationPage.cs行 this.Conversation.StartResumeConversation()评论; 然后你会看到错误未能懒洋洋地初始化角色的集合的CustomerList.aspx+的按钮,点击出现的。 How to keep instances of objects in a mimicry of "conversation scope". Shown in expression="@(convCustomer)['CustomerEditController']". How to enjoy the "extended persistence context". "Lazy load errors" do not happen anymore and repeated calls to ISession.Get to a "same record" do not cause numerous visits to the database, more efficient use of the NHibernate cache. The modifications on "CustomerList.aspx" demonstrate this. To verify the effectiveness of Conversation, comment on "App_Code\ConversationPage.cs" the line this.Conversation.StartResumeConversation(); then you will see the error "failed to lazily initialize a collection of role" occurring at the click of the button "+" on "CustomerList.aspx".

重要提示:不要使用一个会话为整个应用程序(使用HTTP会话相同的时间)。请记住,NHibernate的保持所有加载的对象的高速缓存中,如果会话被保持很长一段时间这缓存趋于无限增长(限制是数据库记录的量)。也就是说,每个谈话应限于该应用程序页面的一个子集,并且必须在相互作用的一端与该子集被丢弃( IConversationState.EndConversation())。建议:保持<属性名=EndPaused值=真/> 在Spring.Conversation.Imple.WebConversationManager,因此,当开始对话的人被丢弃。

IMPORTANT: Never use a single conversation for the entire application (with the same duration of the "HTTP Session"). Remember, NHibernate keeps a cache of all loaded objects, if the conversation is held for a long time this cache tends to grow indefinitely (the limit is the amount of database records). That is, each conversation should be limited to a subset of the application pages, and must be discarded at the end of interaction with this subset (IConversationState.EndConversation()). Recommendation: Keep <property name="EndPaused" value="true"/> in "Spring.Conversation.Imple.WebConversationManager", so when start a conversation the others are discarded.

附加信息:单元测试(Spring.Northwind.IntegrationTests.2008)不工作。但是没有问题的,因为它是不相关的为支持会话的变化,实际上他们已经导致甚至在此之前的错误。

ADDITIONAL INFORMATION: The unit tests ("Spring.Northwind.IntegrationTests.2008") are not working. But there is no problem because it is not related to the changes made to support conversation, in fact they were already resulting in errors even before that.

的变化,Spring.Data.NHibernate.Northwind的文章:

List of changes in "Spring.Data.NHibernate.Northwind":

Spring.Northwind.Web.References.2008 添加链接到schems启用自动完成。 Spring.Northwind.Web.References.2008 Adding links to schems to enable auto complete.

web.config中

web.config

模块,补充说:

module, added:

<add 
  name="ConversationModule" 
  type="Spring.Conversation.HttpModule.ConversationModule, Spring.Conversation"/>  
<add 
  name="ConversationModule" 
  type="Spring.Conversation.HttpModule.ConversationModule, Spring.Conversation"/>

模块,删除:

module, removed:

<add 
  name="OpenSessionInView" 
  type="Spring.Data.NHibernate.Support.OpenSessionInViewModule, Spring.Data.NHibernate21"/>

的web.xml

模块配置 Li urges strong, sustainable, balanced growth

module configurations

<!--Configuration for Spring HttpModule interceptor's-->
<object 
   name="HttpApplicationConfigurer" 
   type="Spring.Context.Support.HttpApplicationConfigurer, Spring.Web">
  <property name="ModuleTemplates">
    <dictionary>
      <entry key="ConversationModule">
        <!-- this name must match the module name -->
        <object>
          <!-- 
          select "view source" in your browser on any page to 
          see the appended html comment
          -->
          <property name="ConversationManagerNameList">
            <list element-type="string">
              <value>conversationManager</value>
            </list>
          </property>
        </object>
      </entry>
    </dictionary>
  </property>
</object>

会话管理器

conversation manager

<!--Conversation Manager-->
<object 
    name="conversationManager" 
    type="Spring.Conversation.Imple.WebConversationManager, Spring.Conversation" 
    scope="session">
  <property name="SessionFactory" ref="NHibernateSessionFactory"/>
  <property name="EndPaused" value="true"/>
</object>

客户对话

Customer Conversation

<!--
 Conversation for 'CustomerEditor.aspx', 'CustomerList.aspx', 
 'CustomerOrders.aspx', 'CustomerView.aspx',  and 'FulfillmentResult.aspx'
-->
<!--
 Important: If the application had other parties
 ("management employees" for example), they should use another 
 conversation.
-->
<object 
    name="convCustomer" 
    type="Spring.Conversation.Imple.WebConversationSpringState, Spring.Conversation" 
    scope="session">
  <property name="Id" value="convCustomer"></property>
  <property name="TimeOut" value="0"></property>
  <property name="ConversationManager" ref="conversationManager"></property>
  <property name="SessionFactory" ref="NHibernateSessionFactory"/>
  <property name="DbProvider" ref="DbProvider"/>
  <!--
    Using workaround for 'conversation scope' to reference for 
    'CustomerEditController'. It is not as volatile as "request scope" 
    not as durable as the "session scope"
  -->
  <property name="['CustomerEditController']" ref="CustomerEditController"></property>
</object>

更改CustomerEditController的范围,删除[范围=会话],并把[单身=假]:

Change "CustomerEditController" scope, remove [scope="session"] and put [singleton="false"]:

<object 
    name="CustomerEditController" 
    type="NHibernateCustomerEditController" 
    singleton="false">
  <constructor-arg name="sessionFactory" ref="NHibernateSessionFactory"/>
</object>
...

更改为CustomerEditController引用删除 REF =CustomerEditController,把 EX pression =@(convCustomer)['CustomerEditController'](模拟对话范围):

Change reference for "CustomerEditController", remove ref="CustomerEditController" and put expression="@(convCustomer)['CustomerEditController']" (Simulating "conversation scope"):

<!--
  Using workaround for 'conversation scope' to reference for 
  'CustomerEditController'. It is not as volatile as "request scope" 
  not as durable as the "session scope"
-->
<object name="CustomerEditPage" abstract="true">
  <property 
    name="CustomerEditController" 
    expression="@(convCustomer)['CustomerEditController']"/>
  <property name="Conversation" ref="convCustomer"/>
</object>

        <!--
          Using workaround for 'conversation scope' to reference for 
          'CustomerEditController'. It is not as volatile as "request scope" 
          not as durable as the "session scope"
        -->
        <object type="CustomerView.aspx">
          <property name="CustomerDao" ref="CustomerDao" />
          <property 
            name="CustomerEditController" 
            expression="@(convCustomer)['CustomerEditController']" />
          <property name="Conversation" ref="convCustomer"/>
          <property name="Results">
            <dictionary>
              <entry key="EditCustomer" value="redirect:CustomerEditor.aspx" />
              <entry key="CustomerList" value="redirect:CustomerList.aspx" />
            </dictionary>
          </property>
        </object>

        <!--
          Using workaround for 'conversation scope' to reference for 
          'CustomerEditController'. It is not as volatile as "request scope" 
          not as durable as the "session scope"
        -->
        <object type="FulfillmentResult.aspx">
          <property name="FulfillmentService" ref="FulfillmentService" />
          <property 
            name="CustomerEditController" 
            expression="@(convCustomer)['CustomerEditController']" />
          <property name="Conversation" ref="convCustomer"/>
          <property name="Results">
            <dictionary>
              <entry key="Back" value="redirect:CustomerOrders.aspx" />
            </dictionary>
          </property>
        </object>

        <object type="Default.aspx">
          <property name="Conversation" ref="convDefault"/>
          <property name="Results">
            <dictionary>
              <entry key="CustomerList" value="redirect:CustomerList.aspx" />
            </dictionary>
          </property>
        </object>

        <!--Conversation for 'Default.aspx'-->
        <!--
          "convDefault" will have only one functionality: trigger the release
          of other conversations when started (StartResumeConversation())
        -->
        <object
            name="convDefault" 
            type="Spring.Conversation.Imple.WebConversationSpringState, Spring.Conversation"
            scope="session">
          <property name="Id" value="convDefault"></property>
          <property name="TimeOut" value="0"></property>
          <property name="ConversationManager" ref="conversationManager"></property>
          <property name="SessionFactory" ref="NHibernateSessionFactory"/>
          <property name="DbProvider" ref="DbProvider"/>
        </object>

新增ConversationPage.cs。基页与对话的支持。 CustomerList.aspx 允许列表中的订购的在同一页上没有延迟初始化错误。所有的对象保持连接到ISession的(NHibernate的)。

Added "ConversationPage.cs". Base page with support for conversation. CustomerList.aspx Allow list the "Order's" on the same page without "lazy initialization error". All objects stay attached to ISession (NHibernate).

添加的属性的IList&LT;客户&GT; CustomersLoadedOncePerConvList 。列表加载只有一次,每个对话搜索数据库只有一次。 更改 Page_InitializeControls 的审议 CustomersLoadedOncePerConvList 。 的方法 BtnShowOrders_Click performe上隐含了延迟加载 Customer.Orders 。 Added property IList<Customer> CustomersLoadedOncePerConvList. List loaded only once, searching the database only once per conversation. Changing the Page_InitializeControls for consider CustomersLoadedOncePerConvList. The method BtnShowOrders_Click performe implicitly a "lazy load" on Customer.Orders. CustomerEditor.aspx.cs CustomerList.aspx.cs CustomerOrders.aspx.cs CustomerView.aspx.cs FullfillmentResult.aspx.cs Default.aspx.cs

Dao.xml

新增&LT;输入键=connection.release_mode值=on_close/&GT; ,以避免在每次IDbCommand的执行后断开,再连接。因为可以在事务边界之外会出现大量lazyloads的这一点很重要。

补充: Added <entry key="connection.release_mode" value="on_close"/> to avoid disconnection and reconnection before and after each IDbCommand execution. This is important because can occur a large numbers of lazyloads outside the transaction boundaries.

Added:

...
<entry key="show_sql" value="true"/>
<entry key="format_sql" value="true"/>
...

从Default.aspx.cs删除(他们从来没有使用过):

Remove from "Default.aspx.cs" (they are never used):

customerDao ; fulfillmentService ; CustomerDao ; 的button1_Click(对象发件人,EventArgs五); ProcessCustomer(); customerDao; fulfillmentService; CustomerDao; Button1_Click(object sender, EventArgs e); ProcessCustomer();

配置\ Log4Net.xml。

Config\Log4Net.xml.

...
<!--detail's about SQL's. To view sql commands on Logs\log.txt-->
<logger name="NHibernate.SQL">
  <level value="DEBUG" />
</logger>
...
<!--detail's about Conversation-->
<logger name="Spring.Conversation">
  <level value="DEBUG" />
</logger>