4

明らかに、間違ったキーワードで検索しています。

オブジェクトがVendorありInvoice、NHibernate プロジェクトでは次のようになります。

public class Vendor
{
    public string theName { get; set; }
}

public class Invoice
{
    public Vendor theVendor { get; set; }
    public decimal Amount { get; set; }
}

VendorRepositoryNHとリポジトリを使用した UnitOfWork スタイルのインターフェイスがありInvoiceRepositoryます...これらは機能しているようです。

次のようにベンダーを簡単に作成できます。

public void CreateVendor(string name)
{
    using (var u = new UnitOfWork())
    {
        var v = new Vendor();
        v.theName = name;
        u.Vendors.Add(v);
        u.Save();
    }
}

Invoiceただし、オブジェクトを作成するには、 への参照が必要Vendorです。これは次のように簡単だと思いました:

public void CreateInvoice(decimal theAmount, string vendorName)
{
    using (var u = new UnitOfWork())
    {
        var i = new Invoice();
        i.Amount = theAmount;
        var v = u.Vendors.GetByName(vendorName);
        i.theVendor = v;
        u.Invoices.Add(i);
        u.Save();
    }
}

ただし、そうではないようです。これには、特別な NHibernate ブードゥー教を行う必要がありますか? 私は NHibernate を UnitOfWork インターフェースの背後に置いておきたいと思っていますが、最小限のコードや混乱でオブジェクトを明確に関連付けたいと考えています。

UPDATE要求ごと: ベンダーのマッピング ファイル (余分なものを削除):

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="DataModel"
                   namespace="DataModel">
    <class name="Vendor" table="Vendors">
        <id name="APVendorId">
            <generator class="guid" />
        </id>
        <property name="theName" index="ixVendorName" length="100" not-null="true" column="VendorName" />
    </class>
</hibernate-mapping>

請求書の場合:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                    assembly="C3.DataModel"
                    namespace="C3.DataModel">
    <class name="Invoice" table="Invoices">
        <id name="InvoiceId">
            <generator class="guid" />
        </id>
        <one-to-one name="Vendor" class="Vendor" constrained="true" cascade="none" fetch="join" />
        <property name="theAmount" column="InvoiceAmount" not-null="true" />
    </class>
</hibernate-mapping>

リポジトリ コードは次のようになります。

///<summary>
///Auto-generated NHibernate repository for the domain POCO object <strong>APInvoice</strong>
///</summary>
public partial class NHInvoiceRepository : IInvoiceRepository
{
    internal ISession _Session;
    internal ITransaction _Transaction;
    private bool _IndependentSession;

    ///<summary>
    ///Adds a Invoice object to the NHibernate repository.
    ///</summary>
    public void Add(Invoice invoice)
    {
        _Session.Save(invoice);
    }

    ///<summary>
    ///Instantiates the repository in standalone (no associated UnitOfWork) mode.  This should usually be avoided.
    ///</summary>
    internal NHInvoiceRepository()
    {
        _Session = NHibernateHelper.OpenSession();
        _Transaction = _Session.BeginTransaction();
        _IndependentSession = true;
    }

    ///<summary>
    ///Instantiates the repository as a part of a UnitOfWork pattern.
    ///</summary>
    public NHInvoiceRepository(ISession session, ITransaction transaction)
    {
        _Session = session;
        _Transaction = transaction;
        _IndependentSession = false;
    }

    ///<summary>
    ///Instantiates the repository as a part of a UnitOfWork pattern.
    ///</summary>
    public NHInvoiceRepository(ISession session)
    {
        _Session = session;
        _Transaction = _Session.BeginTransaction();
        _IndependentSession = false;
    }

    ///<summary>
    ///Implements the IDisposable interface.
    ///</summary>
    public void Dispose()
    {
        _Transaction.Dispose();
        _Session.Dispose();
        return;
    }

    ///<summary>
    ///Commits the changes in the repository in standalone (no associated UnitOfWork) mode.
    ///</summary>
    public void Save()
    {
        if (_IndependentSession)
        {
            _Transaction.Commit();
            _Transaction = _Session.BeginTransaction();
        }
    }

}

UnitOfWork コードは次のようになります。

///<summary>
///UnitOfWork Interface.  The primary data interface between the data model and the persistence layer.
///</summary>
public partial class NHUnitOfWork : IUnitOfWork
{
    private ISession _Session;
    private ITransaction _Transaction;
    public IVendorRepository Vendors { get; private set; }
    public IInvoiceRepository Invoices { get; private set; }

    public void Save()
    {
        Vendors.Save();
        Invoices.Save();
        _Transaction.Commit();
    }

    public void Dispose()
    {
        Vendors.Dispose();
        Invoices.Dispose();
        _Transaction.Dispose();
        _Session.Dispose();
    }

    public NHUnitOfWork()
    {
        _Session = NHibernateHelper.OpenSession();
        _Transaction = _Session.BeginTransaction();
        Vendors = new NHVendorRepository(_Session);
        Invoices = new NHInvoiceRepository(_Session);
    }
}

私が得ているエラーメッセージは次のとおりです。

NHibernate.PropertyValueException: not-null property references a null or transient value 

マッピングで1対1を多対1に変更しようとしましたが、結果は変わりませんでした。

2回目の再コンパイルでUPDATE(およびdbスキーマを再構築)すると、この変更が機能しました。

4

2 に答える 2

3

私はいつも<one-to-one>マッピングに問題があります。に移動することをお勧めします<many-to-one unique="true">

于 2012-06-02T21:31:18.773 に答える
2

問題はこの行にあると思います

<one-to-one name="Vendor" class="Vendor" constrained="true" cascade="none" fetch="join" />

で置き換えてみてください

<many-to-one name="Vendor" unique="true" cascade="all" fetch="join" />
于 2012-06-02T21:50:58.210 に答える