What is the best practice for readonly lists in NHibernate

后端 未结 5 1702
北荒
北荒 2020-12-06 02:32

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

class Order
{
   IList Lines {get;se         


        
相关标签:
5条回答
  • 2020-12-06 02:46

    I expose collections as ReadOnlyCollection and use AddX and RemoveX methods for maintaining the collections. We just switched to 3.5 and I'm thinking about exposing IEnumerable instead. In most cases with NHibernate the child has a reference to the parent so exposing Add and Remove methods allows you to maintain that relationship:

        public void AddPlayer(Player player)
        {
            player.Company = this;
            this._Players.Add(player);
        }
    
        public void RemovePlayer(Player player)
        {
            player.Company = null;
            this._Players.Remove(player);
        }
    
    0 讨论(0)
  • 2020-12-06 02:49

    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>
    
    0 讨论(0)
  • 2020-12-06 02:52

    I have spent several days looking for a best approach for readonly lists in NHibernate. This discussion helped me a lot to form the one that fits our project.

    There is an approach I started to use:

    1. Backing fields are used to store collections
    2. IEnumerable< T> is used to expose collections to force clients use AddLine() and RemoveLine() methods.
    3. ReadOnlyCollection type is used in addition to IEnumerable.

    Code:

    public class Order
    {
        private readonly IList<OrderLine> lines = new List<OrderLine>();
    
        public virtual IEnumerable<OrderLine> Lines
        {
            get
            {
                return new ReadOnlyCollection<OrderLine>(lines);
            }
        }
    
        public void AddLine(OrderLine line)
        {
            if (!lines.Contains(line))
            {
                this.lines.Add(line);
                line.Order = this;
            }
        }
    
        public void RemoveLine(OrderLine line)
        {
            if (lines.Contains(line))
            {
                this.lines.Remove(line);
                line.Order = null;
            }
        }
    }
    
    public class OrderLine
    {
        public Order Order { get; set; }
    }
    
    0 讨论(0)
  • 2020-12-06 02:54

    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().
    
    0 讨论(0)
  • 2020-12-06 02:56

    If I'm exposing a list which shouldn't be modified, then I use IEnumerable and yield. I find it cumbersome trying to use ReadOnlyCollections in conjunction with NHiberante.

    With this approach, you still have the private lines field which gets mapped and populated via NHibernate; however, public access to the collection is performed through iterators. You cannot add to or remove from the underlying list with this Lines property.

    For example:

    public IEnumerable<OrderLine> Lines {
        get {
            foreach (OrderLine aline in lines) {
                yield return aline;
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题