3

I would like to retrive data (list of channels for category).

Here's my model:

public class Category : AuditableEntity<int>
{
    public string Name { get; set; }

    public virtual IEnumerable<CategoryChannel> CategoryChannels { get; set; }
}

public class CategoryChannel : Entity<int>
{
    [Display(Name = "Channel")]
    public string ChannelId { get; set; }

    [ForeignKey("ChannelId")]
    public virtual Channel Channel { get; set; }

    [Display(Name = "Category")]
    public int CategoryId { get; set; }

    [ForeignKey("CategoryId")]
    public virtual Category Category { get; set; }
}

public class Channel : AuditableEntity<string>
{
    public string Name { get; set; }

    public virtual IEnumerable<CategoryChannel> CategoryChannels { get; set; } 
}

And here's my code for retrive data:

    return _entities.Set<Channel>()
        .Include(x => x.CategoryChannels).Where(y => y.Name.Equals(category))
        .AsEnumerable();

And finally I've got an error message:

A specified Include path is not valid. The EntityType 'xxx.Channel' does not declare a navigation property with the name 'CategoryChannels'.

mskuratowski
  • 4,014
  • 15
  • 58
  • 109

1 Answers1

2

IEnumerable<T> can't be a navigation property used for lazy/eager loading, you'll have to use an implementation of ICollection<T> for that (Array, List, HashSet...) or just ICollection<T> itself of course.

IEnumerable is lazy by default because of deferred execution which is why you need an implementation which ensures a local copy of the collection.

Alexander Derck
  • 13,818
  • 5
  • 54
  • 76
  • I've changed my code for List, but now I got empty list (supposed to be 2) – mskuratowski Jan 28 '16 at 09:42
  • You kept the list virtual right? It might be possible EF expects your model to instantiate the List (not entirely sure on this). Try to add a constructor to `Channel`: `public Channel() { CategoryChannel = new List(); }` – Alexander Derck Jan 28 '16 at 09:54
  • Yeah, but I found another problem. I refared to Channel Name ("Where(y => y.Name.Equals(category))" but I should refer to Category Name – mskuratowski Jan 28 '16 at 10:00
  • Conditionally eager loading related entities is not possible. You get them all or you get none, but that's another topic :) – Alexander Derck Jan 28 '16 at 10:01
  • Sure, but if I would like to Lazy Loading it is possible, but I'm looking for how can I do this – mskuratowski Jan 28 '16 at 10:03
  • @Cieja It's not possible. This is a workaround: http://stackoverflow.com/a/34965741/3410196 – Alexander Derck Jan 28 '16 at 10:10
  • Hmm, So how can retrieve Channels by category? I would like List of Channels as a result (not CategoryChannels list) – mskuratowski Jan 28 '16 at 10:17
  • So you have a category already? `var channels = category.CategoryChannels.Select(c => c.Channel).ToList();` – Alexander Derck Jan 28 '16 at 10:23
  • But in this solution I have to create two queries. I have only category as a string, so I would like to retrieve channels by category which I have as a string in one query. – mskuratowski Jan 28 '16 at 10:26
  • You have the category's primary key already, I think you can figure out yourself how to get the category. This site is for specific programming problems like your initial issue, not for writing your code. – Alexander Derck Jan 28 '16 at 10:30