none
Whats the reasoning behind using HashSet for collections in EF code first generation thru EF 6.1 Wizard.. RRS feed

  • Question

  • Hi,

    We are using the code first wizard included with EF 6.1 to generate our models from an existing DB. We are noticing that any one to many relationship is marked as ICollection and in the constructor the concrete implementation is HashSet.

    However, we have other scenarios where we need to pass these models to another rules engine and there the only way it will work is if it is a concrete implementation of List rather than ICollection and HashSet.

    My questions is: What are the reasons for marking all one to many properties as ICollection and using HashSet as default concrete implementation in the EF code first generation wizard?

    Any detailed explanation will help us in avoiding any future pitfall when we change the property from ICollection to List and concrete implemenation from HashSet to List.

    Please let me know if the question is not entirely clear.


    Thanmal Verma

    Tuesday, June 3, 2014 8:25 PM

Answers

  • Hello,

    I think the reply from Anthony Pegram explains the reason:

    Entity Framework would use ICollection<T> because it needs to support Add operations, which are not part of the IEnumerable<T> interface.

    Also note that you were using ICollection<T>, you were merely exposing it as the List<T> implementation. List<T> brings along with it IList<T>, ICollection<T>, and IEnumerable<T>.

    As for your change, exposing via the interface is a good choice, despite List<T> working. The interface defines the contract but not the implementation. The implementation could change. In some instances, perhaps the implementation could be a HashSet<T>, for example. (This is a mindset you could use for more than just Entity Framework, by the way. A good object-oriented practice is to program towards the interface and not the implementation. Implementations can and will change.)

    And if you want the generated type to be List<T>, you can modify the .tt file as:

    In line 50, replacing the “HashSet” with “List” and in line 296, replacing “ICollection” with “List” as:

    this.<#=code.Escape(navigationProperty)#> = new List<<#=typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType())#>>();
    navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("List <" + endType + ">") : endType,

    Then it will generate the List<T> type by default.

    If I misunderstand, please let me know.               

    Regards.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    • Proposed as answer by ErikEJMVP Wednesday, June 4, 2014 8:03 AM
    • Marked as answer by Fred BaoModerator Thursday, June 12, 2014 6:42 AM
    Wednesday, June 4, 2014 5:39 AM
    Moderator