NHibernate: Mapping IList property
I have next tables Order
, Transaction
, Payment
. Class Order
has some properties:
public virtual Guid Id { get; set; }
public virtual DateTime Created { get; set; }
...
and I have added two more:
public virtual IList<Transaction> Transactions { get; set; }
public virtual IList<Payment> Payments { get; set; }
How to keep Transactions
and Payments
lists开发者_C百科 (relations) in the database?
See collection mapping in the reference documentation. There are several ways to map an IList
property.
A bag is an unordered, unindexed collection which may contain the same element multiple times.
<bag name="Transactions" lazy="true" table="Transaction" >
<key column="OrderId"/>
<one-to-many class="Transaction"/>
</bag>
A set is an unordered, unindexed collection which contains unique elements.
<set name="Transactions" lazy="true" table="Transaction" >
<key column="OrderId"/>
<one-to-many class="Transaction"/>
</set>
A list is an ordered and indexed collection which may contain the same element multiple times.
<list name="Transactions" lazy="true" table="Transaction" >
<key column="OrderId"/>
<index column="ordering"/>
<one-to-many class="Transaction"/>
</list>
NHibernate can return the unordered collections in sorted order using the sort attribute.
No discussion of collection mapping us complete without mentioning cascade. This enables operations on the parent entity to apply to the collection entities.
- It does not usually make sense to enable cascade on a
<many-to-one>
or<many-to-many>
association. Cascade is often useful for<one-to-one>
and<one-to-many>
associations. - If the child object's lifespan is bounded by the lifespan of the parent object, make it a life cycle object by specifying cascade="all-delete-orphan".
- Otherwise, you might not need cascade at all. But if you think that you will often be working with the parent and children together in the same transaction, and you want to save yourself some typing, consider using cascade="persist,merge,save-update"
If you control the database then one of the joys of using NHib is that it will generate the database for you, including the foreign keys you need to maintain your lists there. Use the code below to do so:
try
{
var schema = new SchemaExport(cfg);
schema.Drop(false, true);
schema.Create(true, true);
}
catch (Exception ex)
{
Console.WriteLine(@"Schema Export Error Message: {0}", ex);
}
where cfg is your NHibernate Configuration object.
Let us know if that solves your problem, or there is a different question you are asking.
Berryl
I'm not sure what you're asking. Assuming that Transactions
and Payments
are mapped in nhibernate already, you need to add the cascade option to you association mappings for Order
.. In fluent nhibernate, something like this:
References(x => x.Payments)
.Cascade.All
...
That will make sure that when you add transactions/payments to an order, they are persisted.
edit
Regardless of whether or not you're using fluent nhibernate, cascading is the option that (I think) you want. The nhibernate docs for mapping collections are here.
Figured out the working solution for me. In the mapping file I have added:
<bag name="Transactions" lazy="true" table="Transaction" >
<key column="OrderId"/>
<one-to-many class="Transaction"/>
</bag>
<bag name="Payments" lazy="true" table="Payment">
<key column="OrderId"/>
<one-to-many class="Payment"/>
</bag>
精彩评论