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

我有一个带有 NHVendorRepositoryInvoiceRepository存储库的 UnitOfWork 样式界面......这些似乎正在工作。

我可以毫不费力地创建一个供应商,有点像这样:

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 接口后面,但我想干净地将对象与最少的代码或混淆相关联。

更新每个请求:供应商的映射文件(删除了额外的东西):

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

我确实尝试在映射中将一对一更改为多对一,但没有不同的结果。

第二次重新编译时更新,(并重建数据库模式)此更改有效。

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