Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 5980943
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 22, 20262026-05-22T21:52:24+00:00 2026-05-22T21:52:24+00:00

My domain classes that have one-to-many mappings generally take the following form (untested code):

  • 0

My domain classes that have one-to-many mappings generally take the following form (untested code):

public Customer Customer
{
    // Public methods.

    public Order AddOrder(Order order)
    {
        _orders.Add(order);
    }

    public Order GetOrder(long id)
    {
        return _orders.Where(x => x.Id).Single();
    }

    // etc.

    // Private fields.

    private ICollection<Order> _orders = new List<Order>();
}

The EF4 code-only samples I’ve seen expose a public ICollection when dealing with one-to-many relationships.

Is there a way to persist and restore my collections with exposing them? If not, it would appear that my domain objects will be designed to meet the requirements of the ORM, which seems to go against the spirit of the endeavour. Exposing an ICollection (with it’s Add, etc. methods) doesn’t seem particularly clean, and wouldn’t be my default approach.

Update

Found this post that suggests it wasn’t possible in May. Of course, the Microsoft poster did say that they were “strongly considering implementing” it (I’d hope so) and we’re half a year on, so maybe there’s been some progress?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-22T21:52:25+00:00Added an answer on May 22, 2026 at 9:52 pm

    I found that whatever was done, EF requires the ICollection<T> to be public. I think this is because when the objects are loaded from the database, the mapping looks for a collection property, gets the collection and then calls the Add method of the collection to add each of the child objects.

    I wanted to ensure that the addition was done through a method on the parent object so created a solution of wrapping the collection, catching the add and directing it to my preferred method of addition.

    Extending a List and other collection types was not possible because the Add method is not virtual. One option is to extend Collection class and override the InsertItem method.

    I have only focussed on the Add, Remove, and Clear functions of the ICollection<T> interface as those are the ones that can modify the collection.

    First, is my base collection wrapper which implements the ICollection<T> interface
    The default behaviour is that of a normal collection. However, the caller can specify an alternative Add method to be called. In addition, the caller can enforce that the Add, Remove, Clear operations are not permitted by setting the alternatives to null. This results in NotSupportedException being thrown if anyone tries to use the method.

    The throwing of an exception is not as good as preventing access in the first place. However, code should be tested (unit tested) and an exception will be found very quickly and a suitable code change made.

    public abstract class WrappedCollectionBase<T> : ICollection<T>
    {
    
        private ICollection<T> InnerCollection { get { return GetWrappedCollection(); } }
    
        private Action<T> addItemFunction;
        private Func<T, bool> removeItemFunction;
        private Action clearFunction;
    
    
        /// <summary>
        /// Default behaviour is to be like a normal collection
        /// </summary>
        public WrappedCollectionBase()
        {
            this.addItemFunction = this.AddToInnerCollection;
            this.removeItemFunction = this.RemoveFromInnerCollection;
            this.clearFunction = this.ClearInnerCollection;
        }
    
        public WrappedCollectionBase(Action<T> addItemFunction, Func<T, bool> removeItemFunction, Action clearFunction) : this()
        {
            this.addItemFunction = addItemFunction;
            this.removeItemFunction = removeItemFunction;
            this.clearFunction = clearFunction;
        }
    
        protected abstract ICollection<T> GetWrappedCollection();
    
        public void Add(T item)
        {
            if (this.addItemFunction != null)
            {
                this.addItemFunction(item);
            }
            else
            {
                throw new NotSupportedException("Direct addition to this collection is not permitted");
            }
        }
    
        public void AddToInnerCollection(T item)
        {
            this.InnerCollection.Add(item);
        }
    
        public bool Remove(T item)
        {
            if (removeItemFunction != null)
            {
                return removeItemFunction(item);
            }
            else
            {
                throw new NotSupportedException("Direct removal from this collection is not permitted");
            }
        }
    
        public bool RemoveFromInnerCollection(T item)
        {
            return this.InnerCollection.Remove(item);
        }
    
        public void Clear()
        {
            if (this.clearFunction != null)
            {
                this.clearFunction();
            }
            else
            {
                throw new NotSupportedException("Clearing of this collection is not permitted");
            }
        }
    
        public void ClearInnerCollection()
        {
            this.InnerCollection.Clear();
        }
    
        public bool Contains(T item)
        {
            return InnerCollection.Contains(item);
        }
    
        public void CopyTo(T[] array, int arrayIndex)
        {
            InnerCollection.CopyTo(array, arrayIndex);
        }
    
        public int Count
        {
            get { return InnerCollection.Count; }
        }
    
        public bool IsReadOnly
        {
            get { return ((ICollection<T>)this.InnerCollection).IsReadOnly; }
        }
    
        public IEnumerator<T> GetEnumerator()
        {
            return InnerCollection.GetEnumerator();
        }
    
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return InnerCollection.GetEnumerator();
        }
    
    }
    

    Given that base class we can use it in two ways. Examples are using the original post objects.

    1) Create a specific type of wrapped collection (For example, List)
    public class WrappedListCollection : WrappedCollectionBase, IList
    {
    private List innerList;

        public WrappedListCollection(Action<T> addItemFunction, Func<T, bool> removeItemFunction, Action clearFunction)
            : base(addItemFunction, removeItemFunction, clearFunction)
        { 
        this.innerList = new List<T>();
        }
    
        protected override ICollection<T> GetWrappedCollection()
        {
            return this.innerList;
        }
     <...snip....> // fill in implementation of IList if important or don't implement IList
        }
    

    This can then be used:

     public Customer Customer
     {
     public ICollection<Order> Orders {get { return _orders; } }
     // Public methods.
    
     public void AddOrder(Order order)
     {
        _orders.AddToInnerCollection(order);
     }
    
    // Private fields.
    
    private WrappedListCollection<Order> _orders = new WrappedListCollection<Order>(this.AddOrder, null, null);
    }
    

    2) Give a collection to be wrapped using

     public class WrappedCollection<T> : WrappedCollectionBase<T>
    {
        private ICollection<T> wrappedCollection;
    
        public WrappedCollection(ICollection<T> collectionToWrap, Action<T> addItemFunction, Func<T, bool> removeItemFunction, Action clearFunction)
            : base(addItemFunction, removeItemFunction, clearFunction)
        {
            this.wrappedCollection = collectionToWrap;
        }
    
        protected override ICollection<T> GetWrappedCollection()
        {
            return this.wrappedCollection;
        }
    }
    

    which can be used as follows:

    {
    public ICollection Orders {get { return _wrappedOrders; } }
    // Public methods.

     public void AddOrder(Order order)
     {
        _orders.Add(order);
     }
    
    // Private fields.
    private ICollection<Order> _orders = new List<Order>();
    private WrappedCollection<Order> _wrappedOrders = new WrappedCollection<Order>(_orders, this.AddOrder, null, null);
    }
    

    There are some other ways to call the WrappedCollection constructors
    For example, to override add but keep remove and clear as normal

    private WrappedListCollection<Order> _orders = new WrappedListCollection(this.AddOrder,  (Order o) => _orders.RemoveFromInnerCollection(o), () => _orders.ClearInnerCollection());
    

    I agree that it would be best if EF would not require the collection to be public but this solution allows me to control the modification of my collection.

    For the problem of preventing access to the collection for querying you can use approach 2) above and set the WrappedCollection GetEnumerator method to throw a NotSupportedException. Then your GetOrder method can stay as it is. A neater method however may be to expose the wrapped collection. For example:

     public class WrappedCollection<T> : WrappedCollectionBase<T>
     {
        public ICollection<T> InnerCollection { get; private set; }
    
        public WrappedCollection(ICollection<T> collectionToWrap, Action<T> addItemFunction, Func<T, bool> removeItemFunction, Action clearFunction)
            : base(addItemFunction, removeItemFunction, clearFunction)
        {
            this.InnerCollection = collectionToWrap;
        }
    
    
        protected  override ICollection<T> GetWrappedCollection()
        {
            return this.InnerCollection;
        }
    }
    

    Then the call in the GetOrder method would become

    _orders.InnerCollection.Where(x => x.Id == id).Single();
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

In my domain, an Employee and a Department have a one-to-many bidirectional relationship; to
suppose I have a domain classes: public class Country { string name; IList<Region> regions;
Given the following domain classes: class Post { SortedSet tags static hasMany = [tags:
Here are the domain model classes: public abstract class BaseClass { ... } public
We're using interfaces to represent entity classes in our domain model. We have concrete
In my domain model I have an abstract class CommunicationChannelSpecification, which has child classes
We have many classes published in a remoting channel as singlecalls. The application resides
So standard Agile philosophy would recommend making your domain classes simple POCOs which are
I am developing a C++ class library containing domain model classes, and I would
We have a simple domain model: Contact, TelephoneNumber and ContactRepository. Contact is entity, it

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.