Я искал неправильные ключевые слова.NHibernate: связать существующий объект с новым объектом?
У меня есть объекты на Vendor
Invoice
и в проекте NHibernate, как так:
public class Vendor
{
public string theName { get; set; }
}
public class Invoice
{
public Vendor theVendor { get; set; }
public decimal Amount { get; set; }
}
У меня есть интерфейс в стиле UnitOfWork с NH VendorRepository
и 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 По желанию: Mapping файл (дополнительный материал удален) для поставщика:
<?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();
}
}
}
The 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
Я попытаться изменить один к одному на многие-к-одному в соответствиях, без различных результатов ,
ОБНОВЛЕНИЕ на втором этапе перекомпиляции (и восстановление схемы db) это изменение сработало.
Почему бы не метод требует экземпляр поставщика вместо этого? Это имело бы смысл для меня: public void CreateInvoice (decimal theAmount, поставщик поставщика); ' –
Я думаю, что проблема связана с вашими сопоставлениями, можете ли вы разместить сопоставления ваших двух классов? – Jupaol
Он должен хорошо работать с NHibernate. Как работают 'Vendors.Add()' и 'UnitOfWork.Save()'? – ivowiblo