tags:

views:

281

answers:

4

I have a table Order, Transaction, Payment. Class Order has the properties:

public virtual Guid Id { get; set; }
public virtual DateTime Created { get; set; }
...

I added properties:

public virtual IList<Transaction> Transactions { get; set; }
public virtual IList<Payment> Payments { get; set; }

These properties contain a record of tables [Transaction] and [Payment]. How to keep these lists in the database?

A: 

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.

Gabe Moothart
Yes, Transactions and Payments are mapped in nhibernate already.
Anry
But I don't use Fluent Nhibernate in my project.
Anry
+1  A: 

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

Berryl
A: 

Found the answer. In the mapping file 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>
Anry
+1  A: 

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"
Lachlan Roche