通用ADO.Exception NHibernate

ale*_*ale 4 nhibernate hibernate

我有这张桌子:

表"Set":[PK:IdSet(int),IdProject(int),IdSetState(int),IdPriority(int),NumSet(int),Unit(nchar),NumDisc(int)]

所以,我让Test NUnit在这个表中插入一个值.这是我的测试方法:

[Test]
public void Can_add_Set()
{
      var set = new Set { IdProject = 2, IdSetState = 2, NumDisc = 1, IdPriority = 3, NumSet = 100};
      setRepository.AddSet(set);
 }
Run Code Online (Sandbox Code Playgroud)

这是我的插入方法:

public void AddSet(Set set) 
    {
        using (ISession session = NHibernateSessionBuilder.OpenSession())
        using (ITransaction transaction = session.BeginTransaction())
        {
            session.Save(set);
            transaction.Commit();
        }
    }
Run Code Online (Sandbox Code Playgroud)

这是Set.hbm.xml:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="AdminProject"
                   namespace="AdminProject.Business.Entity">

  <class name="Set">
    <id name="IdSet">
      <generator class="identity"/>
    </id>
    <property name="IdProject" />
    <property name="IdSetState" />
    <property name="IdPriority" />
    <property name="Unit" />
    <property name="NumDisc" />
    <property name="NumSet" />
  </class>

</hibernate-mapping> 
Run Code Online (Sandbox Code Playgroud)

session.save(set); 显示此错误:

通用ADO.Exception

"无法加载实体:[AdminProject.Business.Entity.Set#5] [SQL:SELECT set0_.IdSet as IdSet2_0_,set0_.IdProject as IdProject2_0_,set0_.IdSetState as IdSetState2_0_,set0_.IdPriority as IdPriority2_0_,set0_.Unit as Unit2_0_,set0_.NumDisc为NumDisc2_0_,set0_.NumSet为NumSet2_0_ FROM Set set0_ WHERE set0_.IdSet =?]"

Kei*_*thS 9

当NHibernate抛出这样的异常时,它包含ADO提供程序抛出的内部异常,99%的时间会确切地说出失败的SQL语句出了什么问题.内在的例外更有帮助; NH只是将它包含在更通用的内容中,因此您可以捕获泛型异常,而不是NH用于传输SQL的实际ADO.NET层抛出的所有可能的特定于提供程序的异常.

根据您的显示,我的第一个怀疑是DB中的列的名称与您的属性不完全相同,并且您没有在映射中指定不同的列名.如果仅指定属性,则属性和列名称必须根据DB的排序规则匹配(基本上意味着唯一可能的区别可能是大小写,并且仅在不区分大小写的DB中).

另一件事,与错误无关:您的AddSet()函数不允许外部事务控制,因为每个操作不仅仅是它自己的事务,而是它自己的会话.这通常是个坏主意,因为如果必须同时添加Set 1和Set 2,则插入Set 1,然后Set 2失败,Set 1仍然在DB中.通常,您必须能够告诉NHibernate多个操作应该是全有或全无,通过允许代码获取一些Transaction或UnitOfWork引用,它可以传递到各种存储库方法以识别事务上下文.