2015-04-07 46 views
0

刚开始在我的ASP.NET MVC应用程序中使用NHibernate。例如,我创建了两个表格:书籍和章节。NHibernate多个表。 ASP.NET MVC

CREATE TABLE [dbo].[Books] (
    [Id] INT NOT NULL PRIMARY KEY IDENTITY, 
    [Title] NVARCHAR (50) NOT NULL, 
    [Author] NVARCHAR (50) NOT NULL,  
); 

CREATE TABLE [dbo].[Chapters] (
    [Id] INT NOT NULL PRIMARY KEY IDENTITY, 
    [Title]  NVARCHAR (MAX) NOT NULL, 
    [Notes]  TEXT   NULL, 
    [ChapterIndex] INT   NULL, 
    [BookId]  INT   NULL,  
    CONSTRAINT [FK_Chapters_ToTable] FOREIGN KEY (BookId) REFERENCES Books(Id) 
); 

NHibernate的配置文件:

<?xml version="1.0" encoding="utf-8" ?> 
    <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2"> 
     <session-factory> 
     <property name="connection.provider"> 
      NHibernate.Connection.DriverConnectionProvider 
     </property> 
     <property name="connection.driver_class"> 
      NHibernate.Driver.SqlClientDriver 
     </property> 
     <property name="connection.connection_string"> 
      Data Source= LocalDB)\v11.0;AttachDbFilename="c:\users\anton\documents\visual studio 2013\Projects\Books\Books\App_Data\BooksDB.mdf";Integrated Security=True 
     </property> 
     <property name="dialect"> 
      NHibernate.Dialect.MsSql2012Dialect 
     </property> 
     </session-factory> 
    </hibernate-configuration> 

Book.hmb.xls映射文件

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true" assembly="Books" namespace="Books.Models"> 

    <class name="Book" table="Books" dynamic-update="true"> 
    <cache usage="read-write"/> 
    <id name="Id" column="Id" type="int"> 
     <generator class="native" /> 
    </id> 
    <property name="Title" not-null="true" /> 
    <property name="Author" not-null="true"/> 
    <list name="Chapters" cascade="all-delete-orphan"> 
     <key column="BookId"/> 
     <index column="ChapterIndex"/> 
     <one-to-many class="Chapter"/> 
    </list> 
    </class> 

    <class name="Chapter" table="Chapters" dynamic-update="true"> 
    <cache usage="read-write"/> 
    <id name="Id" column="Id" type="int"> 
     <generator class="native" /> 
    </id> 
    <property name="Title" not-null="true" /> 
    <property name="Notes" /> 
    </class> 
</hibernate-mapping> 

Book模型

namespace Books.Models 
{ 
    public class Book 
    { 
     public virtual int Id { get; set; } 
     public virtual string Title { get; set; } 
     public virtual string Author { get; set; } 
     public virtual IList<Chapter> Chapters { get; set; } 
    } 
} 

章模型

namespace Books.Models 
{ 
    public class Chapter 
    { 
     public virtual int Id { get; set; } 
     public virtual string Title { get; set; } 
     public virtual string Notes { get; set; } 
    } 
} 

会话模型

namespace Books.Models 
{ 
    public class NHibernateSession 
    { 

     public static ISession OpenSessionBooks() 
     { 
      var configuration = new Configuration(); 
      var configurationPath = HttpContext.Current.Server.MapPath(@"~\Models\NHibernate\hibernate.cfg.xml"); 
      configuration.Configure(configurationPath); 
      var booksConfigurationFile = HttpContext.Current.Server.MapPath(@"~\Models\NHibernate\Book.hbm.xml"); 
      configuration.AddFile(booksConfigurationFile); 
      ISessionFactory sessionFactory = configuration.BuildSessionFactory(); 
      return sessionFactory.OpenSession(); 

     } 

    } 
} 

BookController的问题部分

public ActionResult Details(int id) 
     { 
      using (ISession session = NHibernateSession.OpenSessionBooks()) 
      { 
       var book = session.Get<Book>(id); 
       return View(book); 
      } 
     } 

在这里,我期待着与加载图书详情所有章节列表的详细信息。

的ActionResult详细强类型的视图:

@model Books.Models.Book 

@{ 
    ViewBag.Title = "Details"; 
} 

<h2>Details</h2> 

<fieldset> 
    <legend>Book</legend> 

    <div class="display-label"> 
     @Html.DisplayNameFor(model => model.Title) 
    </div> 
    <div class="display-field"> 
     @Html.DisplayFor(model => model.Title) 
    </div> 

    <div class="display-label"> 
     @Html.DisplayNameFor(model => model.Author) 
    </div> 
    <div class="display-field"> 
     @Html.DisplayFor(model => model.Author) 
    </div> 

    <div class="display-label"> 
     @Html.DisplayNameFor(model => model.Chapters) 
    </div> 
    <div class="display-field"> 
     @Html.DisplayFor(model => model.Chapters) 
    </div> 

</fieldset> 
<p> 
    @Html.ActionLink("Edit", "Edit", new { id=Model.Id }) | 
    @Html.ActionLink("Back to List", "Index") 
</p> 

应用程序无法在视线

 @Html.DisplayNameFor(model => model.Chapters) 

随着例外

Initializing[Books.Models.Book#7]-failed to lazily initialize a collection of role: Books.Models.Book.Chapters, no session or session was closed 

请帮我这个话题!解决方案.7z存档可用here

回答

0

的原因是因为提到Keith Nicholas是各分会延迟加载。有许多方法来解决这个问题,

1.使用DTO作为模型

你可以使用一个BookDTO和因此,当视图显示了所有必要的模型ChapterDTO列表在地方数据

2.在该请求寿命

为此,您需要为每个在一个单一的会话绑定的请求,并在整个请求的生命时使用的请求方法使用会话的会话。请参阅this了解更多详情。

2

您的章节被延迟加载。然而,当你的视图被渲染时,它们只会被加载。届时您的会议将关闭。

解决这个问题的两种方法。

力当你有一个会话

负载离开会话打开网页渲染也