Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework Many to many through containing object

I was curious if it is possible to map an intermediate table through a containing object.

public class Subscriber : IEntity
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    private ChannelList _subscribedList { get; set; }
    public int NumSubscribedChannels { get { return _subscribedList.Count(); } }
}

public class HelpChannel : IEntity
{
    [Key]
    public int Id { get; set; }
    public string name { get; set; }
    public string category { get; set; }
    public int group { get; set; }
}

I need to have a subscriber table, channel table and an intermediate table to link a subscriber to his/her channels.

Is it possible to map the list that is within the ChannelList object to the Subscriber Model?

I figured that's probably not possible and that I would need to just have a private List for EF to map. But I wasn't sure if EF will do that for private variables. Will it?

I'm hoping that is does because if it has to be public to maintain the encapsulation.

like image 696
Glen Nicol Avatar asked Dec 10 '12 19:12

Glen Nicol


1 Answers

You can map private properties in EF code-first. Here is a nice description how to do it. In your case it is about the mapping of Subscriber._subscribedList. What you can't do is this (in the context's override of OnModelCreating):

modelBuilder.Entity<Subscriber>().HasMany(x => x._subscribedList);

It won't compile, because _subscribedList is private.

What you can do is create a nested mapping class in Subscriber:

public class Subscriber : IEntity
{
    ...
    private ICollection<HelpChannel> _subscribedList { get; set; } // ICollection!

    public class SubscriberMapper : EntityTypeConfiguration<Subscriber>
    {
        public SubscriberMapper()
        {
            HasMany(s => s._subscribedList);
        }
    }
}

and in OnModelCreating:

modelBuilder.Configurations.Add(new Subscriber.SubscriberMapping());

You may want to make _subscribedList protected virtual, to allow lazy loading. But it is even possible to do eager loading with Include:

context.Subscribers.Include("_subscribedList");
like image 114
Gert Arnold Avatar answered Oct 04 '22 13:10

Gert Arnold