Search code examples
c#entity-frameworkef-code-firstnavigation-properties

Why does Stack<T> not work as a navigation propery in EF


I came across this by chance; I defined a navigation property as Stack; though the DB relation is created fine when I tried to query the entity using Include it says A specified Include path is not valid. The EntityType 'BreakAway.Destination' does not declare a navigation property with the name 'Lodgings'. According to accepted answer of this post as long as the navigation property type implements ICollection it should be fine. I just double check that Stack<T> does implement ICollection

The entities are:

 public class Destination
    {
        public Destination()
        {
            Lodgings = new Stack<Lodging>();
        }

        public string Name { get; set; }
        public string Country { get; set; }
        public int DestinationId { get; set; }
        public string Description { get; set; }
        public byte[] Photos { get; set; }
        public virtual Stack<Lodging> Lodgings { get; set; }
    }

  public sealed class Lodging
    {
        public int LodgingId { get; set; }
        public string Name { get; set; }
        public string Owner { get; set; }
        public bool IsResort { get; set; }
        public decimal MilesFromNearestAirport { get; set; }
        public Destination Destination { get; set; }
        public int DestinationId { get; set; }
    }

Simple testing query:

        private static void QueryDestination()
        {
            using (var context = new Context())
            {
                var dest = context.Destinations.Include(d => d.Lodgings).First();
                Console.WriteLine("Destination Name: {0}",dest.Name);
                Console.WriteLine("Lodging Name " + dest.Lodgings.First().Name);

            }
        }

Solution

  • Navigation properties need to be of a type that implements ICollection<T> not ICollection. Stack<T> only implements ICollection.

    Quoting from this reference:

    A navigation property that represents the "many" end of a relationship must return a type that implements ICollection, where T is the type of the object at the other end of the relationship.

    ICollection in the reference has a link that points to the MSDN reference for ICollection<T>.