Nhibernate“无法初始化集合”

Posted

技术标签:

【中文标题】Nhibernate“无法初始化集合”【英文标题】:Nhibernate "could not initialize a collection" 【发布时间】:2017-08-30 07:25:57 【问题描述】:

我的 NHibernate 一对多映射存在以下问题。如果我想通过我的 API 方法获取所有客户,则会收到以下错误:

"$id":"1","Message":"发生错误。","ExceptionMessage":"The “ObjectContent`1”类型无法序列化响应正文 内容类型'文本/html; charset=utf-8'.","ExceptionType":"System.InvalidOperationException","StackTrace":null,"InnerException":"$id":"2","Message":"An 发生错误。","ExceptionMessage":"无法初始化 集合:[Designet.Models.Customer.Orders#1][SQL:SELECT orders0_.CustomerId 作为 Custom2_2_1_,orders0_.Id 作为 Id1_2_1_, orders0_.Id 作为 Id1_2_0_,orders0_.CustomerId 作为 Custom2_2_0_, orders0_.Description 为 Descri3_2_0_,orders0_.Price 为 Price4_2_0_, orders0_.Created as Create5_2_0_, orders0_.Deadline as Deadli6_2_0_ FROM Order orders0_ WHERE orders0_.CustomerId=?]","ExceptionType":"NHibernate.Exceptions.GenericADOException","StackTrace":" w NHibernate.Loader.Loader.LoadCollection(ISessionImplementor 会话, 对象 id,IType 类型)\r\n

我在下面粘贴了我的代码。我一直在寻找我在谷歌和 SO 上的问题的答案,但是人们提出的建议没有任何帮助。我不明白代码的哪一部分会引发错误。也许你有一些提议,我应该怎么做,来解决这个问题?我会很高兴得到您的帮助。

客户模型:

public class Customer
    
        public virtual int Id  get; set; 
        public virtual string Name  get; set; 

        public virtual IList<Order> Orders  get; set; 

        public Customer()
        
            Orders = new List<Order>();
        
    

客户映射:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true"
                   assembly="Designet" namespace="Designet.Models">
  <class name="Customer" table="Customer" dynamic-update="true" lazy="true" >
    <cache usage="read-write"/>
    <id name="Id" column="Id" type="int">
      <generator class="native" />
    </id>
    <property name="Name" />
    <bag name="Orders" lazy="true" inverse="true" >
      <key column="CustomerId"/>
      <one-to-many class="Designet.Models.Order"/>
    </bag>    
  </class>
</hibernate-mapping>

客户数据库:

CREATE TABLE [dbo].[Customer] (
    [Id]   INT            IDENTITY (1, 1) NOT NULL,
    [Name] NVARCHAR (255) NULL,
    PRIMARY KEY CLUSTERED ([Id] ASC)
);

订购型号:

 public class Order
    
        public virtual int Id  get; set; 
        public virtual string Description  get; set; 
        public virtual decimal Price  get; set; 
        public virtual DateTime Created  get; set; 
        public virtual DateTime Deadline  get; set; 

        public virtual int CustomerId  get; set; 
        public virtual Customer Customer  get; set; 

    

订单映射:

    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true"
                   assembly="Designet" namespace="Designet.Models"
    <class name="Order" table="Order" dynamic-update="true" lazy="true" > 
    <cache usage="read-write"/>
    <id name="Id" column="Id" type="int">
      <generator class="native" />
    </id>

    <many-to-one name="Customer" column="CustomerId"/>

    <property name="Description" />
    <property name="Price" />
    <property name="Created" />
    <property name="Deadline" />
    <property name="CustomerId" not-null="true" />

  </class>
</hibernate-mapping>

订单数据库:

CREATE TABLE [dbo].[Order] (
    [Id]          INT            IDENTITY (1, 1) NOT NULL,
    [Description] NVARCHAR (MAX) NULL,
    [Price]       SMALLMONEY     NULL,
    [Created]     DATETIME       NOT NULL,
    [Deadline]    DATETIME       NULL,
    [CustomerId]  INT            NOT NULL,
    PRIMARY KEY CLUSTERED ([Id] ASC),
    FOREIGN KEY ([CustomerId]) REFERENCES [dbo].[Customer] ([Id])
);

【问题讨论】:

【参考方案1】:

您的评论json链接中的内部异常写Incorrect syntax near the keyword 'Order'.您的表名为Order,这是一个SQL关键字。它必须逃脱。为此使用向后倾斜。

<class name="Order" table="`Order`" ...

映射语义正确性的注意事项:bag 应该映射为 ICollection&lt;&gt; 而不是 IList&lt;&gt;IList&lt;&gt; 用于映射list:一个集合,其中每个元素都有一个记录在数据库中的索引,从零到集合大小减一,没有任何漏洞。你不太可能希望这样。

此外,对于您的模型,您应该使用set 而不是bagbag 允许重复。您的模型不允许它们,一个订单在客户订单集合中可能只出现一次。如果您更改为 set,请在代码中使用 ISet&lt;&gt;

关于您的问题的说明 您的错误消息被截断,不允许检查您的问题的原因。 GenericADOException 应该包含另一个 InnerException,但您提供的消息没有显示它。

请获取完整的异常消息,并尝试以可读的方式发布:“漂亮打印”您的 JSON,或者更好的是,获取异常 .ToString() 输出。

【讨论】:

我已将bag 更改为set,并将IList&lt;&gt; 更改为ISet&lt;&gt;,但这并没有帮助。有一个完整的错误:jsoneditoronline.org/?id=48b540615c2550df97c1cafdb3550502 它包含了您的问题的答案。答案已编辑。

以上是关于Nhibernate“无法初始化集合”的主要内容,如果未能解决你的问题,请参考以下文章

NHIbernate 和安全/业务层

如果我使用类似 NHibernate 的 ORM,为啥需要 LINQ?

使用 NHibernate 的示例查询

Abp.NHibernate连接PostgreSQl数据库

NHibernate之旅系列文章导航

Nhibernate学习教程-- 第一个NHibernate程序