Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best practice for readonly lists in NHibernate

Domain Model I am working on has root aggregate and child entities. Something like the following code:

class Order
{
   IList<OrderLine> Lines {get;set;}
}

class OrderLine
{
}

Now I want my Order to control lines. Something like that:

class Order
{
   OrderLine[] Lines {get;}

   void AddLine(OrderLine line);
}

At this time we are using the following pattern:

class Order
{
   private IList<OrderLine> lines = new List<OrderLine>();
   OrderLine[] Lines {get {return this.lines;}}

   void AddLine(OrderLine line)
   {
      this.orders.Add(line);
   {
}

NHibernate is mapped directly to the lines field.

Now questions...

  • What do you practice in such situations?
  • Does anyone use methods: public IEnumerable GetLines()
  • What are you using as return type for property? May be ReadOnlyCollection or IEnumerable;
  • May be this is not the best place to ask? Suggest please.

Update: Seems IEnumerable wins, however solution still is not perfect...

like image 912
Mike Chaliy Avatar asked Mar 14 '09 13:03

Mike Chaliy


2 Answers

I do it like this:

public class Order
{
      private ISet<OrderLine> _orderLines = new HashedSet<OrderLine>();

      public ReadOnlyCollection<OrderLine> OrderLines
      {
          get { return new List<OrderLine>(_orderLines).AsReadOnly(); }
      }

      public void AddOrderLine( OrderLine ol )
      {
          ...
      }
}

Then, offcourse, in the mapping, NHibernate is told to use the _orderLines field:

<set name="OrderLine" access="field.camelcase-underscore" ... >
...
</set>
like image 169
Frederik Gheysels Avatar answered Nov 10 '22 06:11

Frederik Gheysels


The pattern I use is:

class Order
{
   private List<OrderLine> lines = new List<OrderLine>();

   IEnumerable<OrderLine> Lines { get { return this.lines; } }

   void AddLine(OrderLine line)
   {
       this.orders.Add(line);
   }
}

If you're using NET 3.5 you get all the search functionality you could want for IEnumerable using LINQ, and you hide your collection implementation.

The problem with returning OrderLine[] is that your collection can be modified externally eg:

Order.Lines[0] = new OrderLine().
like image 36
gcores Avatar answered Nov 10 '22 06:11

gcores