LazyLoading not behaving as expected in EFCore

Here are 2 (minimized classes):

    (Index(nameof(Name), IsUnique = true))
    public partial class ParticipantList
    {
        public ParticipantList()
        {
            Emails = new HashSet<Email>();
        }

        (Key)
        (Column("id"))
        public long Id { get; set; }
        //...
        (InverseProperty(nameof(Email.ParticipantList)))
        public virtual ICollection<Email> Emails { get ; set; }
    }

    public partial class Email
    {
        (Key)
        (Column("id", TypeName = "integer"))
        public long Id { get; set; }
        (Column("participant_list_id", TypeName = "integer"))
        public long? ParticipantListId { get; set; }
        /...
        (ForeignKey(nameof(ParticipantListId)))
        (InverseProperty("Emails"))
        public virtual ParticipantList ParticipantList { get; set; }

    }

And the DbContext OnConfiguring method contains:

                optionsBuilder
                    .UseLazyLoadingProxies()
                    .UseSqlite(...);

And the DBContext OnModelCreating method contains:

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Email>(entity =>
            {
                entity.HasOne(d => d.ParticipantList)
                    .WithMany(p => p.Emails)
                    .HasForeignKey(d => d.ParticipantListId)
                    .OnDelete(DeleteBehavior.ClientSetNull);
            });

This is what works:

var email = _db.Emails.Find(1);
// email.ParticipantList (this lazy loads just fine).

What doesn’t work:

var plist = _db.ParticipantLists.Find(1);
// plist.Emails.Count() == 0  (this doesn't lazy load at all)
// plist.Emails.Count == 0    (again no lazy loading)
// plist.Emails.ToList()      (empty list, no lazy loading)

I should insert a rant here about the stupidity of having both Count() and Count with different meanings here. I mean, seriously, who is going to catch that during a code review????

This is most likely due to:

        public ParticipantList()
        {
            Emails = new HashSet<Email>();
        }

Which was created by the ef-scaffold app. I mean it makes sense, the HashSet is empty, but it seems like the model should override the access to the HashSet and do the lazy loading.

The problem is that if you remove this:

        public ParticipantList()
        {
            // Emails = new HashSet<Email>();
        }

And then call this code:

// plist.Emails.Count() == 0  (Now you get a null reference exception 
//                             because guess what:  Emails is not initialized!)
// plist.Emails.ToList()      (Also gives a null reference exception)
// plist.Emails.Count == 0    (Again, a null reference exception)

The documentation shows code like this (note that Posts is NOT initialized in the example at https://docs.microsoft.com/en-us/ef/core/querying/related-data/lazy ):

public class Blog
{
    public int Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Post> Posts { get; set; }
}

public class Post
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public virtual Blog Blog { get; set; }
}

Which will purportedly lazy load the Posts from the Blog. But when I follow that pattern and remove the ctor that initializes Emails/Posts I get a null reference exception.

To add to the mystery/madness is this:

var email = _db.Emails.Find(1);
var plist = _db.ParticipantLists.Find(1);
// plist.Emails.Count() == 1 (It knows about the relation and added it to 
//                            the Emails HashSet on the ParticipantList!)

So, how do I get Emails to LazyLoad. I know about the 1 + N problem, and I’m not worried about that aspect, but I’d like the models to load when they are requested.