CreditMemo、CreditMemoDetail、SalesInvoice、ReceivablesRecord、TransactionType の 5 つのドメイン オブジェクトを持つブラウン フィールド アプリケーションがあります。CreditMemo は 1 つであり、CreditMemoDetail を含む多数です。また、SalesInvoice との多対 1 です。SalesInvoice は ReceivablesRecord と 1 対多で、TransactionType とは多対 1 です (以下の xml マッピング)。直接の親/子以外の値に依存する関係はありません。
Get(id) を実行すると、構造全体が正しく返されます。CreditMemo の列が正しく入力され、ISet が正しく、SalesInvoice/ReceivablesRecord/TransactionType 階層全体が完全に入力されます。Get (invoiceNumber) を実行すると、SalesInvoice オブジェクトは正しく入力されますが、ISet は空です。NHProfiler を使用すると、パラメーターを含め、まったく同じクエリが実行されます。私はこれを何時間もノックしてきましたが、意味のあるものを思いつくことができませんでした.
総当たり攻撃ができることはわかっていますが、CreditMemo から開始するとリレーションシップが自動的に機能し、SalesInvoice から開始すると関係が自動的に機能しないという事実に頭がおかしくなりました。何か案は?
オブジェクトとマッピング:
public class CreditMemo
{
public virtual int CreditMemoId { get; set; }
public virtual string CreditMemoNumber { get; set; }
public virtual DateTime CreditDate { get; set; }
public virtual string InvoiceNumber { get; set; }
public virtual string ReturnToStock { get; set; }
public virtual string Posted { get; set; }
public virtual string Notes { get; set; }
public virtual Iesi.Collections.Generic.ISet<CreditMemoDetail> Details { get; set; }
public virtual SalesInvoice InvoiceInfo { get; set; }
}
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true" schema="aladdin" namespace="Receivables.Models">
<class name="Receivables.Models.CreditMemo, Receivables" lazy="false" table="credit_memo">
<id name="CreditMemoId" column="credit_memo_id">
<generator class="identity" />
</id>
<property name="InvoiceNumber" column="invoice_no" />
<property name="CreditMemoNumber" column="credit_memo_no" />
<property name="CreditDate" column="credit_date" type="DateTime" />
<property name="ReturnToStock" column="return_to_stock" />
<property name="Posted" column="posted" />
<property name="Notes" column="notes" />
<many-to-one name="InvoiceInfo" class="SalesInvoice" column="invoice_no" update="false" insert="false" />
<set name="Details" cascade="delete">
<key column="credit_memo_id" />
<one-to-many class="CreditMemoDetail"/>
</set>
</class>
</hibernate-mapping>
public class CreditMemoDetail
{
public virtual int CreditMemoDetailId { get; set; }
public virtual int CreditMemoId { get; set; }
public virtual string CreditType { get; set; }
public virtual decimal Amount { get; set; }
public virtual string AffectCommission { get; set; }
}
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true" schema="aladdin" namespace="Receivables.Models">
<class name="Receivables.Models.CreditMemoDetail, Receivables" lazy="false" table="cr_memo_detail">
<id name="CreditMemoDetailId" column="crmemodetailid">
<generator class="identity" />
</id>
<property name="CreditMemoId" column="credit_memo_id" />
<property name="CreditType" column="credit_type" />
<property name="Amount" column="amount" />
<property name="AffectCommission" column="affect_commission" />
</class>
</hibernate-mapping>
public class SalesInvoice
{
public virtual string InvoiceNumber { get; set; }
public virtual string Customer { get; set; }
public virtual DateTime InvoiceDate { get; set; }
public virtual string SalesPerson { get; set; }
public virtual string ClassOfSale { get; set; }
public virtual Iesi.Collections.Generic.ISet<ReceivablesRecord> Transactions { get; set; }
}
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true" schema="aladdin" namespace="Receivables.Models">
<class name="Receivables.Models.SalesInvoice, Receivables" lazy="false" table="invoice">
<id name="InvoiceNumber" column="invoice_no">
<generator class="assigned" />
</id>
<property name="Customer" column="customer" />
<property name="InvoiceDate" column="invoice_date" type="DateTime" />
<property name="SalesPerson" column="salesman" />
<property name="ClassOfSale" column="class" />
<set name="Transactions">
<key column="invoice_no" />
<one-to-many class="ReceivablesRecord"/>
</set>
</class>
</hibernate-mapping>
public class ReceivablesRecord
{
public virtual string InvoiceNumber { get; set; }
public virtual DateTime AccrecDate { get; set; }
public virtual string TxType { get; set; }
public virtual decimal Amount { get; set; }
public virtual string Note { get; set; }
public virtual TransactionType TypeInfo { get; set; }
public override bool Equals(object obj)
{
bool result = false;
try
{
ReceivablesRecord input = (ReceivablesRecord)obj;
if (InvoiceNumber == input.InvoiceNumber && AccrecDate == input.AccrecDate && TxType == input.TxType)
{
result = true;
}
}
catch (Exception ex)
{
}
return result;
}
public override int GetHashCode()
{
return string.Format("{0}{1}{2}", InvoiceNumber, AccrecDate, TxType).GetHashCode();
}
}
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true" schema="aladdin" namespace="Receivables.Models">
<class name="Receivables.Models.ReceivablesRecord, Receivables" lazy="false" table="accrec">
<composite-id>
<key-property name="InvoiceNumber" column="invoice_no" />
<key-property name="AccrecDate" column="accrec_date" type="DateTime" />
<key-property name="TxType" column="tx_type" />
</composite-id>
<property name="Amount" column="amount" />
<property name="Note" column="note" />
<many-to-one name="TypeInfo" class="TransactionType" column="tx_type" />
</class>
</hibernate-mapping>
public class TransactionType
{
public virtual string TransactionCode { get; set; }
public virtual string Description { get; set; }
public virtual decimal GLAccountNumber { get; set; }
public virtual string Taxable { get; set; }
}
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true" schema="aladdin" namespace="Receivables.Models">
<class name="Receivables.Models.TransactionType, Receivables" lazy="false" table="txtype">
<id name="TransactionCode" column="tx_code">
<generator class="assigned" />
</id>
<property name="Description" column="description" />
<property name="GLAccountNumber" column="gl_account_no" type="Decimal" />
<property name="Taxable" column="taxable" />
</class>
</hibernate-mapping>
リポジトリ コード:
public CreditMemo GetById(int id)
{
return NhSession.Get<CreditMemo>(id);
}
public SalesInvoice GetInvoiceByInvoiceNumber(string id)
{
SalesInvoice salesInvoice = NhSession.Get<SalesInvoice>(id);
return salesInvoice;
}
動作する代替の GetInvoiceByInvoiceNumber (つまり、マッピングを変更せずに、SalesInvoice より下のすべての詳細レベルを返します) :
return NhSession.CreateQuery("from SalesInvoice where InvoiceNumber = :invoice_no")
.SetString("invoice_no", id).UniqueResult<SalesInvoice>();