带有nHibernate的MVC3 Razor

时间:2011-08-27 09:40:52

标签: nhibernate asp.net-mvc-3 razor nunit

作为着名的ORM,我们决定使用asp.net mvc3来使用nHIbernate。我们按以下方式设置项目:

  1. NHibernate Repository [包含nhibernate的映射,服务和存储库]
  2. MVC3 [这是一个用户界面]
  3. 测试MVC NHibernate [这是一个使用NUnit的测试项目]
  4. 在上面,写了[]文字,清楚说明各层。

    一切正常,意味着传递所有单元测试以进行映射,插入,更新,删除操作。 不幸的是,当我们从mvc3应用程序执行相同的操作时,它会抛出以下错误:

       "An exception occurred during configuration of persistence layer."   
    

    完整堆栈跟踪如下:

       at NHibernate.Cfg.ConfigurationSchema.HibernateConfiguration..ctor(XmlReader hbConfigurationReader, Boolean fromAppSetting) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Cfg\ConfigurationSchema\HibernateConfiguration.cs:line 55
       at NHibernate.Cfg.ConfigurationSchema.HibernateConfiguration..ctor(XmlReader hbConfigurationReader) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Cfg\ConfigurationSchema\HibernateConfiguration.cs:line 36
       at NHibernate.Cfg.Configuration.Configure(XmlReader textReader) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Cfg\Configuration.cs:line 1511
       at NHibernate.Cfg.Configuration.Configure(String fileName, Boolean ignoreSessionFactoryConfig) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Cfg\Configuration.cs:line 1433
       at NHibernate.Cfg.Configuration.Configure(String fileName) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Cfg\Configuration.cs:line 1418
       at NHibernate.Cfg.Configuration.Configure() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Cfg\Configuration.cs:line 1404
       at examplemvcapp.NHibernateRepository..ctor() in D:\example\examplemvcapp-NHExample\examplemvcapp\NHibernateRepository.cs:line 33
       at examplemvcapp_NHExample.UI.Models.CreateAppraisalModel..ctor() in D:\example\examplemvcapp-NHExample\examplemvcapp-NHExample.UI\Models\Department.cs:line 70  
    

    请注意,NHIbernate的所有配置设置在MVC3应用程序中与在Test项目中相同。

    以下是我们得到例外的人:

    using (var nhr = new NHibernateRepository())
    {
        this.Departments = nhr.GetAll<Departments>().Select(x => new SelectListItem 
            {
                Text = x.Departmentdescription, Value = x.Id.ToString()
            });
    }
    

    上面会提出以下内容并提出异常:

    public NHibernateRepository()
    {
        if (sessionFactory == null)
        {
            config = new Configuration();
            config.Configure();
            config.AddAssembly(typeof(NHibernateRepository).Assembly);
            sessionFactory = config.BuildSessionFactory();
        }
        Session = sessionFactory.OpenSession();
        transaction = Session.BeginTransaction();
        Rollback = false;
    }
    

    以上在测试项目中运行良好:

    using (var nhr = new NHibernateRepository())
    {
        var DeptList = nhr.GetAll<Departments>();
    }
    

    以下是放置在NHibernateRepository项目中的hibernate.cfg.xml文件:

    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">  
      <session-factory>
        <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
        <property name="connection.connection_string">Data Source=(local);Initial Catalog=myDatabaseName;Integrated Security=True</property>
        <property name="show_sql">true</property>
        <property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
        <property name="cache.use_query_cache">false</property>
        <property name="adonet.batch_size">100</property>
        <property name="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
    
      </session-factory>
    </hibernate-configuration>
    

    除此之外,这个项目还有NHibernate所需的所有dll。

    在测试项目中,没有特殊的配置设置,只需添加Repository项目的引用以及其所需的其他程序集及其正常工作。

    在MVC3应用程序项目中也保持了同样的效果。

    这方面的任何帮助都是最值得赞赏的。

    此致

2 个答案:

答案 0 :(得分:1)

我不确定这是否会解决您当前的问题,但我确实提出了一些建议。首先,通过HttpModule在Global.asax或(我的偏好)中实现每请求会话会话管理。这是一个简单的例子:

public class NHHttpModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.EndRequest += ApplicationEndRequest;
        context.BeginRequest += ApplicationBeginRequest;
    }

    public void ApplicationBeginRequest(object sender, EventArgs e)
    {
        CurrentSessionContext.Bind(SessionFactory.GetNewSession());
    }

    public void ApplicationEndRequest(object sender, EventArgs e)
    {
        var currentSession = CurrentSessionContext.Unbind(SessionFactory.GetSessionFactory());
        currentSession.Close();
        currentSession.Dispose();
    }

    public void Dispose()
    {
        // Do nothing
    }
}

请注意,这也会在请求管理期间绑定当前会话上下文。

另外,请确保您正在设置正确的会话上下文。测试应该使用thread上下文,但Web应用程序应该使用web上下文。我个人通过Fluent NHibernate配置它,但我相信XML配置文件它会显示为:

<property name="current_session_context_class">web</property>

同样,我通常使用FNH进行配置,因此请验证。

答案 1 :(得分:1)

Per @Michael - 我通过提供以下答案来结束这个帖子,我在研究期间找到了答案。

我们需要做两件事才能找到合适的解决方案;

  1. 如果使用XML文件,我们需要将它们设置为Embedded in properties
  2. 如果不使用xml文件 - 我们需要编译
  3. 要设置上述内容,只需从solution explorere中选择文件名,然后按F4或查看属性窗口,右键单击文件名,然后单击属性链接。

    谢谢大家 - 谁回答了上述问题。