显然,我正在搜索错误的关键字。
我在NHibernate项目中有对象Vendor
和Invoice
,如下所示:
public class Vendor
{
public string theName { get; set; }
}
public class Invoice
{
public Vendor theVendor { get; set; }
public decimal Amount { get; set; }
}
我有一个与NH VendorRepository
和InvoiceRepository
存储库的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
我确实尝试在映射中将一对一更改为多对一,但没有不同的结果。
第二次重新编译时,UPDATE (并重建数据库模式)此更改有效。
答案 0 :(得分:3)
我总是遇到<one-to-one>
映射的麻烦。我建议转到<many-to-one unique="true">
答案 1 :(得分: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" />