Я нахожусь в процессе или изучаю NHibernate, так что терпите меня.
У меня есть класс Order и класс Transaction. Заказ имеет отношение один ко многим с транзакцией. Таблица транзакций в моей базе данных имеет ненулевое ограничение на внешний ключ OrderId.
Класс заказа:
public class Order {
public virtual Guid Id { get; set; }
public virtual DateTime CreatedOn { get; set; }
public virtual decimal Total { get; set; }
public virtual ICollection<Transaction> Transactions { get; set; }
public Order() {
Transactions = new HashSet<Transaction>();
}
}
Отображение заказа:
<class name="Order" table="Orders">
<cache usage="read-write"/>
<id name="Id">
<generator class="guid"/>
</id>
<property name="CreatedOn" type="datetime"/>
<property name="Total" type="decimal"/>
<set name="Transactions" table="Transactions" lazy="false" inverse="true">
<key column="OrderId"/>
<one-to-many class="Transaction"/>
</set>
Класс транзакции:
public class Transaction {
public virtual Guid Id { get; set; }
public virtual DateTime ExecutedOn { get; set; }
public virtual bool Success { get; set; }
public virtual Order Order { get; set; }
}
Отображение транзакции:
<class name="Transaction" table="Transactions">
<cache usage="read-write"/>
<id name="Id" column="Id" type="Guid">
<generator class="guid"/>
</id>
<property name="ExecutedOn" type="datetime"/>
<property name="Success" type="bool"/>
<many-to-one name="Order" class="Order" column="OrderId" not-null="true"/>
На самом деле я не хочу двунаправленной ассоциации. Нет необходимости, чтобы мои объекты транзакций ссылались на объект своего заказа напрямую (мне просто нужен доступ к транзакциям заказа). Однако я должен был добавить это, чтобы Order.Transactions сохранялся в базе данных:
Repository:
public void Update(Order entity)
{
using (ISession session = NHibernateHelper.OpenSession()) {
using (ITransaction transaction = session.BeginTransaction()) {
session.Update(entity);
foreach (var tx in entity.Transactions) {
tx.Order = entity;
session.SaveOrUpdate(tx);
}
transaction.Commit();
}
}
}
Моя проблема заключается в том, что при этом будет выпускаться обновление для каждой транзакции в коллекции заказов (независимо от того, изменилось ли это или нет).
То, что я пытался обойти, - это явное сохранение транзакции перед сохранением заказа, вместо этого просто добавьте транзакции в заказ и затем сохраните заказ:
public void Can_add_transaction_to_existing_order()
{
var orderRepo = new OrderRepository();
var order = orderRepo.GetById(new Guid("aa3b5d04-c5c8-4ad9-9b3e-9ce73e488a9f"));
Transaction tx = new Transaction();
tx.ExecutedOn = DateTime.Now;
tx.Success = true;
order.Transactions.Add(tx);
orderRepo.Update(order);
}
Несмотря на то, что я нашел довольно много статей, посвященных установлению связи «один ко многим», в большинстве из них обсуждается извлечение данных, а не их сохранение.
Большое спасибо,
Бен