0

I have a Code First app with Entity Framework 6. I've run across a problem where EF seems to be messing with my constructors in bizarre ways.

public class ParentClass
{
    public int ParentClassId { get; set; }
    public string SomeField { get; set; }
    public IList<ChildClass> ChildClasses { get; set; }

    public ParentClass()
    {
        BodySingleton.Instance.Strings.Add(SomeField);
    }

    public class ChildClass
    {
        public int ChildClassId { get; set; }
        public string SomeOtherField { get; set; }

        public ChildClass()
        {
            BodySingleton.Instance.Strings.Add(SomeOtherField);
        }
    }
}

public sealed class BodySingleton
{
    public List<string> Strings { get; set; }

    static BodySingleton()
    {
    }

    private BodySingleton()
    {
        Strings = new List<string>();
    }

    public static BodySingleton Instance { get; } = new BodySingleton();
}

The above is an approximation of the live code, which is much more complex. I haven't set up EF for this psuedo code so I haven't actually run the above, but I believe it should have the same problem.

So what happens here is the constructor for ParentClass works as intended, but ChildClass does not. What's weird is that some things with ChildClass work; for instance, if I add a line like SomeOtherField = "Hello, world"; to the constructor, that will work as intended. But it seems like anything I do that tries to interact with other objects do not work. I've also found that debug breaks work with the ParentClass but are completely bypassed by the ChildClass constructor.

Any idea what's happening here? All I can figure is that it's some bug with EF, but it's driving me bonkers and I can't figure out a workaround.

Jason Hamje
  • 401
  • 1
  • 4
  • 11
  • Hey, EF is written in C#, it can't do things you can't do with normal or reflection code. It requires public parameterless constructors and calls them (via reflection), so there is no way to bypass your constructor code. – Ivan Stoev Dec 06 '18 at 17:06
  • Keep in mind that EF won't load your `ChildClass` until you access it. Try this and see if you can hit a breakpoint in the constructor: `myDbContext.Parents.First().ChildClasses.ToList();` – MikeH Dec 06 '18 at 17:23
  • @MikeH Hmm that does seem to work. Your comment made me realize I had an error in my example, the ```ChildClasses``` property is actually an IList not a List. That makes a lot of sense, the constructor is firing when I'm examining the variable, not when I'm running the script. Is there a way I can have EF load everything automatically? – Jason Hamje Dec 06 '18 at 18:06

1 Answers1

1

In your db call to get the object you can use:

ParentClass par;
using (DbContext _context = new DbContext(connectionstring))
{
    par = _context.ParentClass
        .Include(c=>c.ChildClasses) //This include loads also the children
        .Single(p => p.ParentClassId  == 1);

}

Should insure your contructors get called

Aldert
  • 3,286
  • 1
  • 6
  • 18
  • Is there a way to include the entire structure? My structure is quite complex and I'm trying to avoid having to map out the entire structure by hand. I've done some searching and the answer seems to be "no" but I wonder if I'm missing something. – Jason Hamje Dec 06 '18 at 18:43
  • Turn off lazy loading: On the ModelCreating method of DbContext have: this.Configuration.LazyLoadingEnabled = false; see also: https://stackoverflow.com/questions/24022957/entity-framework-how-to-disable-lazy-loading-for-specific-query – Aldert Dec 06 '18 at 18:45
  • I've tried that before but it doesn't seem to do anything =\ – Jason Hamje Dec 06 '18 at 18:52
  • Should work, have you tried to place it in constructor of context? http://www.entityframeworktutorial.net/lazyloading-in-entity-framework.aspx – Aldert Dec 06 '18 at 18:59
  • I ended up using a bunch of includes, wish I could get that LazyLoadingEnabled function to work but I've tried putting it everywhere I can think of and it doesn't want to function. At least the problem is solved, thanks again :) – Jason Hamje Dec 07 '18 at 15:08
  • 1
    Good to her you msnaged to get it work. I will investigate the lazy loadi g a bit more myself. Just to see if i can get it work. Good weekend to you – Aldert Dec 07 '18 at 17:44