foundy_mike
foundy_mike

Reputation:

Filter child collection returned with Aggregate Root using Nhibernate

I'm trying filter the child collection of an aggregate root when loading it with Nhibernate. Load a Customer with all their Orders that have been shipped. Is this possible?

Upvotes: 5

Views: 2185

Answers (4)

Frederik Gheysels
Frederik Gheysels

Reputation: 56984

ICriteria crit = session.CreateCriteria (typeof(Customer));

crit.CreateAlias ("Orders", "o");
crit.Add (Expression.Eq ("o.Status", shippedStatus));
crit.Add (Expression.Eq ("Id", customerId));

return crit.UniqueResult <Customer>();

something like that.

Upvotes: 1

Sebastian Markb&#229;ge
Sebastian Markb&#229;ge

Reputation: 3275

You can also do it using HQL using session.Filter(customer.Orders, "where this.Status == 'Shipped'");

Upvotes: 1

kͩeͣmͮpͥ ͩ
kͩeͣmͮpͥ ͩ

Reputation: 7856

You could look at it the other way - load all the shipped orders for a Customer.

session.CreateCriteria( typeOf(Order) )
    .Add( Restrictions.Eq("Shipped", shippedStatus ) )
    .Add( Restrictions.Eq("Customer", requiredCustomer) )
    .List<Order>();

Upvotes: 1

Tim Scott
Tim Scott

Reputation: 15205

Well, you can expose properties that are filtered in the map, like so:

<bag name="shippedOrders" ... where="Status == 'Shipped'" >
   <key column="CustomerId" />
   <one-to-many class="Order" />
</bag>

The 'where' attribute is arbitrary SQL.

Theoretically you could have two properties of Customer, Orders and ShippedOrders. However, I should say that I have not done this, and I would want to test how NH handles cascading in this case. In any case, you will have to take care when new items are added/removed that they are added/removed correctly to both collections.

The fact that you want to do this makes we wonder if Order is an aggregate root. It might be less trouble in the long run doing it like this:

orderRepository.GetOrders(int customerId, OrderStatus[] statuses)

Upvotes: 3

Related Questions