我正在学习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持久保存到数据库:
存储库:
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);
}
虽然我发现了很多关于建立一对多关联的文章,但大多数都讨论了检索数据而不是坚持回来。
非常感谢, 本
答案 0 :(得分:3)
您需要在映射上设置cascade属性,以便将持久性级联到子对象:
<set name="Transactions" table="Transactions" lazy="false" inverse="true" cascade="all-delete-orphan">
您的Order对象应该有一个AddTransaction方法,用于设置子对象的父引用。类似的东西:
public void AddTransaction(Transaction txn)
{
txn.Order = this;
Transactions.Add(txn);
}
这将导致在持久化订单时持久化Transaction对象。您可以使用internal
修饰符公开Transaction上的Order属性,以使其不公开显示。