none
Lazy Loading Collections

    Question

  • I want to write pure domain classes such as

    public class Product

    {

       public IEnumerable<Photo> Photos {get; private set;}

       public void AddPhoto(){...}

       public void RemovePhoto(){...}


     }

    But the entity framework requires an ICollection type for lazy loading!  The above code no longer works as designed since clients can bypass the AddPhoto / RemovePhoto method and directly call the add method on ICollection.  This is not good.

    public class Product

    {

       public ICollection<Photo> Photos {get; private set;} //Bad code

       public void AddPhoto(){...}

       public void RemovePhoto(){...}


     }

    Any suggestions?

    Wednesday, May 19, 2010 3:15 PM

Answers

  • The Entity Framework doesn't support collection properties that are exposed as IEnumerable<T> with Add and Remove methods. Lazy loading works by the EF generating a derived type at runtime and this is also not possible if the getter is not public or protected. One option you have is to make your collection a protected property and then write your own access to it:

    public class Product

    {

       // This is a mapped property

       protected virtual ICollection<Photo> PhotosInternal { get; set; }

       // This is an un-mapped property that just wraps PhotosInternal:

        public IEnumerable<Photo> Photos

       {

          get  { return PhotosInternal; }

          set { // add all photos from 'value' to PhotosInternal }

       }

       public void AddPhoto(){...}

       public void RemovePhoto(){...}

    }

     

    Jeff


    This posting is provided "AS IS" with no warranties, and confers no rights.
    Wednesday, May 19, 2010 9:56 PM
    Moderator
  • Hi,

     

    The protected properties can be only accessed in derived classes even among the classes in different assemblies.  It’s a C# language feature.   Also, Jeff declare the PhotoInternal property as protected virtual, so it can be override in the derived classes.  http://msdn.microsoft.com/en-us/library/9fkccyh4.aspx.

     

    Hope it helps!

     

    Have a nice weekend, both!

     

    Best Regards,
    Lingzhi Sun

    MSDN Subscriber Support in Forum

    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Friday, May 21, 2010 3:17 AM
    Moderator

All replies

  • The Entity Framework doesn't support collection properties that are exposed as IEnumerable<T> with Add and Remove methods. Lazy loading works by the EF generating a derived type at runtime and this is also not possible if the getter is not public or protected. One option you have is to make your collection a protected property and then write your own access to it:

    public class Product

    {

       // This is a mapped property

       protected virtual ICollection<Photo> PhotosInternal { get; set; }

       // This is an un-mapped property that just wraps PhotosInternal:

        public IEnumerable<Photo> Photos

       {

          get  { return PhotosInternal; }

          set { // add all photos from 'value' to PhotosInternal }

       }

       public void AddPhoto(){...}

       public void RemovePhoto(){...}

    }

     

    Jeff


    This posting is provided "AS IS" with no warranties, and confers no rights.
    Wednesday, May 19, 2010 9:56 PM
    Moderator
  • Thanks.  But what if my model class and entity framework configuration settings are in separate assemblies?  There is no way for the protected property to visible?
    Thursday, May 20, 2010 1:47 PM
  • Hi,

     

    The protected properties can be only accessed in derived classes even among the classes in different assemblies.  It’s a C# language feature.   Also, Jeff declare the PhotoInternal property as protected virtual, so it can be override in the derived classes.  http://msdn.microsoft.com/en-us/library/9fkccyh4.aspx.

     

    Hope it helps!

     

    Have a nice weekend, both!

     

    Best Regards,
    Lingzhi Sun

    MSDN Subscriber Support in Forum

    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Friday, May 21, 2010 3:17 AM
    Moderator
  • Hi,

     

    I am writing to check the status of the issue on your side.  Would you mind letting us know the result of the suggestions? 

     

    If you need further assistance, please feel free to let me know.   I will be more than happy to be of assistance.

     

    Have a nice day!

     

     

    Best Regards,
    Lingzhi Sun

    MSDN Subscriber Support in Forum

    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Tuesday, May 25, 2010 1:19 AM
    Moderator
  • I am also interested to know if this solution worked. (Entity Framework 4.1)

    Anyone can confirm ?

    Thanks!

    Wednesday, September 14, 2011 3:45 PM