【问题标题】:Nhibernate mapping a class which has a generic list propertyNhibernate 映射具有通用列表属性的类
【发布时间】:2013-03-16 14:20:42
【问题描述】:

我是 Nhibernate 的新手,我正在尝试使用 Nhibernate 映射一个具有通用列表属性的类(发票),但我不断得到 错误:“表 InvoiceDetails 中的关联引用了未映射的类:System.Int32”。 因为每张发票都有更多详细信息,所以我对 Invoices 和 InvoiceDetails 表之间的一对多关系进行了讨论。

详情: a) 发票类:

public class Invoice
{
    private IList<InvoiceDetail> _invoiceDetails = new List<InvoiceDetail>();

    public virtual int InvoiceID { get; set; }
    public virtual string SerialNumber { get; set; }
    public virtual string Number { get; set; }
    public virtual DateTime InvoiceDate { get; set; }
    public virtual decimal Amount { get; set; }
    public virtual IList<InvoiceDetail> InvoiceDetails
    {
        get { return _invoiceDetails; }
        set { _invoiceDetails = value; }
    }
    public virtual Customer customer { get; set; }
    public virtual Institution Institution { get; set; }
    public virtual Receipt receipt { get; set; }
    public virtual bool IsDeleted { get; set; }
}

b) InvoiceDetail 类:

public class InvoiceDetail
{
    public virtual int InvoiceDetailID { get; set; }
    public virtual int InvoiceID { get; set; }
    public virtual string ServiceDescription { get; set; }
    public virtual string Unit { get; set; }
    public virtual int Quantity { get; set; }
    public virtual double Value { get; set; }
    public virtual bool IsDeleted { get; set; }
}

c) 发票映射文件:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
    assembly="MyProject" namespace="MyProject.Model">
    <class name="Invoice" table="Invoices">
        <id name="InvoiceID" column="InvoiceID" type="int">
            <generator class="native"></generator>
        </id>
        <property name="SerialNumber" column ="InvoiceSerialNumber"/>
        <property name="Number" column ="InvoiceNumber"/>
        <property name="InvoiceDate"/>
        <property name="Amount"/>
        <property name="IsDeleted" />
        <many-to-one name="Institution" column="InstitutionID" />
        <bag name="InvoiceDetails" access="nosetter.camelcase"
            inverse ="true" lazy ="false" cascade="all-delete-orphan">
            <key column="InvoiceID"/>
            <many-to-one class="MyProject.Model.InvoiceDetail, MyProject"/>
        </bag>
    </class>
</hibernate-mapping>

d) InvoiceDetail 映射文件:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
    assembly="MyProject" namespace="MyProject.Model">
    <class name="InvoiceDetail" table="InvoiceDetails">
        <id name="InvoiceDetailID" column="InvoiceDetailID" type="int">
            <generator class="native"></generator>
         </id>
         <many-to-one name="InvoiceID" column="InvoiceID" />
         <property name="ServiceDescription"/>
         <property name="Unit"/>
         <property name="Quantity"/>
         <property name="Value"/>
         <property name="IsDeleted" />    
     </class>
 </hibernate-mapping>

【问题讨论】:

  • 您的多对一 InvoiceID 似乎有误。它应该是一个属性。或者属性 InvoiceID 的类型应该像多对一 Invoice.Institution :一个类。 (并且属性名称应该改为Invoice)

标签: c# nhibernate nhibernate-mapping generic-list


【解决方案1】:

看起来不错!

修复 InvoiceID

您需要修复 InvoiceDetail.InvoiceID 属性。对于多对一属性,您应该将它们建模为对父实体的引用,而不仅仅是包含 ID 的简单值属性。 Invoice.Institution 是正确的。

InvoiceDetail,替换这个...

public virtual int InvoiceID { get; set; }

...用这个:

public virtual Invoice Invoice { get; set; }

同样,在您的映射中,替换这个...

<many-to-one name="InvoiceID" column="InvoiceID" />

...用这个:

<many-to-one name="Invoice" column="InvoiceID" />

修复包

另外,一个包不能是多对一的——它应该是一对多的。请参阅Documentation。替换这个...

<bag name="InvoiceDetails" access="nosetter.camelcase" inverse ="true" lazy ="false" cascade="all-delete-orphan">
  <key column="InvoiceID"/>
  <many-to-one class="MyProject.Model.InvoiceDetail, MyProject"/>
</bag>

...用这个:

<bag name="InvoiceDetails" access="nosetter.camelcase" inverse ="true" lazy ="false" cascade="all-delete-orphan">
  <key column="InvoiceID"/>
  <one-to-many class="MyProject.Model.InvoiceDetail, MyProject"/>
</bag>

注意 Lazy=False

最后一点:注意lazy="false"。如果您打算让 NHibernate 急切地获取那些相关记录来提高性能,那么这不是这样做的方法。请参阅http://ayende.com/blog/4573/nhibernate-is-lazy-just-live-with-it 了解为什么这是一个问题。请参阅http://nhibernate.info/doc/nh/en/index.html#performance-fetching 了解正确实现此功能的各种方法。

【讨论】:

  • 谢谢,但现在我收到另一个错误:“MyProject.Mappings.Invoice.hbm.xml(17,8): XML 验证错误:命名空间 'urn:nhibernate- 中的元素 'bag' mapping-2.2' 在命名空间 'urn:nhibernate-mapping-2.2' 中有无效的子元素 'many-to-one'。预期的可能元素列表:'element,one-to-many,many-to-many,composite-命名空间'urn:nhibernate-mapping-2.2'中的元素,多对任意'。”有什么想法吗?
  • 糟糕。我应该注意到第一个绕过去。您收到了非常好的错误消息。这个错误信息是完全正确的——一个包不能是多对一的。它应该是一对多的。更新我的答案。
  • 非常感谢您的帮助,Daniel Schilling。我遇到了另一个错误,即在类 Invoice 中找不到属性或提交 invoiceDetails,但我将私有属性的名称从 _invoiceDetails 更改为 invoiceDetails,现在它按预期工作。我将查看发布的链接,在应用程序的几乎所有部分中,带有lazy =“true”的映射将派上用场。干杯! :D
猜你喜欢
  • 2017-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
  • 2010-11-06
  • 1970-01-01
相关资源
最近更新 更多