1

我是 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>
4

1 回答 1

0

Looks pretty good!

Fix InvoiceID

You need to fix the InvoiceDetail.InvoiceID property. With many-to-one properties, you should model them as references to the parent entity instead of just as simple value properties containing an ID. You got it right with Invoice.Institution.

In InvoiceDetail, replace this...

public virtual int InvoiceID { get; set; }

... with this:

public virtual Invoice Invoice { get; set; }

Likewise, in your mappings, replace this...

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

... with this:

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

Fix Bag

Also, a bag cannot be many-to-one - it should be one-to-many. See the Documentation. Replace this...

<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>

... with this:

<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>

Caution about Lazy=False

One final note: be careful with lazy="false". If you are intending to improve performance be having NHibernate eagerly fetch those related records, this is not the way to do it. See http://ayende.com/blog/4573/nhibernate-is-lazy-just-live-with-it for an explanation of why this is a problem. Refer to http://nhibernate.info/doc/nh/en/index.html#performance-fetching for the various way to implement this correctly.

于 2013-03-26T20:54:33.343 回答