Alex Rivera | Logout

DDD: entity's collection and repositories

Asked 2009-08-31T08:27:49.953
14

Suppose I have

public class Product: Entity
{
   public IList<Item> Items { get; set; }
}

Suppose I want to find an item with max something... I can add the method Product.GetMaxItemSmth() and do it with Linq (from i in Items select i.smth).Max()) or with a manual loop or whatever. Now, the problem is that this will load the full collection into memory.

The correct solution will be to do a specific DB query, but domain entities do not have access to repositories, right? So either I do

productRepository.GetMaxItemSmth(product)

(which is ugly, no?), or even if entities have access to repositories, I use IProductRepository from entity

product.GetMaxItemSmth() { return Service.GetRepository<IProductRepository>().GetMaxItemSmth(); }

which is also ugly and is a duplication of code. I can even go fancy and do an extension

public static IList<Item> GetMaxItemSmth(this Product product)
{
   return Service.GetRepository<IProductRepository>().GetMaxItemSmth();
}

which is better only because it doesn't really clutter the entity with repository... but still does method duplication.

Now, this is the problem of whether to use product.GetMaxItemSmth() or productRepository.GetMaxItemSmth(product)... again. Did I miss something in DDD? What is the correct way here? Just use productRepository.GetMaxItemSmth(product)? Is this what everyone uses and are happy with?

I just don't feel it is right... if I can't access a product's Items from the product itself, why do I need this collection in Product at all??? And then, can Product do anything useful if it can't use specific queries and access its collections without performance hits?

Of course, I can use a less efficient way and n

Edit
Report

2 Answers

3

(Disclaimer, I am just starting to get a grasp on DDD. or at least believe doing it :) )

I will second Mark on this one and emphasize 2 point that took me some times to realize.

  • Think about your object in term of aggregates, which lead to

    The point is that either you load the children together with the parent or you load them separately

The difficult part is to think about the aggregate for your problem at hand and not to focus the DB structure supporting it.
An example that emphasizes this point i customer.Orders. Do you really need all the orders of your customer for adding a new order? usually not. what if she has 1 millin of them?
You might need something like OutstandingAmount or AmountBuyedLastMonth in order to fulfill some scenarios like "AcceptNewOrder" or ApplyCustomerCareProgram.

  • Is the product the real aggregate root for your sceanrio?

    What if Product is not an Aggregate Root?

i.e. are you going to manipulate the item or the product?
If it is the product, do you need the ItemWithMaxSomething or do you need MaxSomethingOfItemsInProduct?

  • Another myth: PI means You don't need to think about the DB

Given that you really need the item with maxSomething in your scenario, then you need to know what it means in terms of database operation in order to choose the right implementation, either through a service or a property.
For example if a product has a huge number of items, a solution might be to have the ID of the Item recorded with the product in the db instead of iterating over the all list.

The difficult part for me in DDD is to define the right aggregates. I feel more and more that if I need to rely on lazy loading then I might have overseen some context boundary.

hope this helps :)

answered 2009-08-31T11:27:05.303
0

Remember that NHibernate is a mapper between the database and your objects. Your issue appears to me that your object model is not a viable relational model, and that's ok, but you need to embrace that.

Why not map another collection to your Product entity that uses the power of your relational model to load in an efficient manner. Am I right in assuming that the logic to select this special collection is not rocket science and could easily be implemented in filtered NHibernate mapped collection?

I know my answer has been vague, but I only understand your question in general terms. My point is that you will have problems if you treat your relational database in an object oriented manner. Tools like NHibernate exist to bridge the gap between them, not to treat them in the same way. Feel free to ask me to clarify any points I didn't make clear.

answered 2009-09-02T23:37:57.457

Your Answer