Entity framework 6 Lazy loading with db initiation

2019-07-30 06:24发布

问题:

I am working with EF 6 and Lazy loading.

class MainPrograme
{
    static void Main(string[] args)
    {
        ProgramContext _dbContext = new ProgramContext();

        _dbContext.Programs.Add(new Program
        {
            SecondProgram = new SecondProgram
            {
                Title = "Demo"
            }
        });
        _dbContext.SaveChanges();
        var item = _dbContext.Programs.Find(1);
    }
}

Once I disable lazy loading with

    Configuration.LazyLoadingEnabled = false; 

It works fine. No relational objects are loaded. item.SecondProgram is null. Perfect. However when I delete the database, my db initiation sets up a new db and then lazy loading is not working. If I run the above program again, then lazy loading works fine again. Do you guys have any idea why ? Thanks.

Here is my constructor

public ProgramContext()
        : base("Data Source=xxx;")
    {
        Configuration.LazyLoadingEnabled = false;
        if (!Database.Exists())
        {
            Task.Run(InitializeDatabase).Wait();
        }
    }

If database does not exist, InitializeDatabase will setup the db and if I do a db query in the same context instance, lazy loading fails. If I create a new context object and query db via that, lazy loading works.

Update -

Below is my full console program. Run it and check SecondProgram property if the item. It is not null. Lazy loading not worked there. Then run the program again without deleting the database and check SecondProgram property again. Is is null as expected. Why is was not null in the first run ?

class MainPrograme
{
    static void Main(string[] args)
    {
        ProgramContext _dbContext = new ProgramContext();

        _dbContext.Programs.Add(new Program
        {
            SecondProgram = new SecondProgram
            {
                Title = "Demo"
            }
        });
        _dbContext.SaveChanges();
        var item = _dbContext.Programs.Find(1);
    }
}

public class Program
{
    public int Id { get; set; }
    public string Title { get; set; }

    public virtual ICollection<SecondProgram> SecondPrograms { get; set; }
    public virtual SecondProgram SecondProgram { get; set; }
}

public class SecondProgram
{
    public int Id { get; set; }
    public string Title { get; set; }

}

public class ProgramContext : DbContext
{
    public ProgramContext()
        : base("Data Source=XXX;Initial Catalog=MyContainer;Integrated Security=True;")
    {
        Configuration.LazyLoadingEnabled = false;
    }

    public DbSet<Program> Programs { get; set; }
}

回答1:

Lazy loading can be turned off for all entities in the context by setting a flag on the Configuration property as shown below.Please check whether you have done that or not.

example:

 public class MyContext : DbContext 
    { 
        public MyContext() //constructor
        { 
            this.Configuration.LazyLoadingEnabled = false; 
        } 
    }

Note : You can still Load related entities by using Eager Loading

Update :

can you use this :

Database.SetInitializer<ProgramContext>(new CreateDatabaseIfNotExists<ProgramContext>());

Instead of your code :

 if (!Database.Exists())
    {
      Task.Run(InitializeDatabase).Wait();
    }

Update 2 :

Your problem here is you haven't used this keyword with the Configuration property.You have to set it as shown below.

 this.Configuration.LazyLoadingEnabled = false; 


回答2:

In this case I am checking for the SecondProgram on the same context that I used to create it in the first place. It is already loaded with SecondProgram. Therefore it is not null.

ProgramContext _dbContext = new ProgramContext();

    _dbContext.Programs.Add(new Program
    {
        SecondProgram = new SecondProgram
        {
            Title = "Demo"
        }
    });
    _dbContext.SaveChanges();
    var item = _dbContext.Programs.Find(1);

When I create a new context object and access Program like

ProgramContext _newContext = new ProgramContext();
var item = _newContext.Programs.Find(1);

Then we are talking about lazy loding coz it has to load stuff from db. Now it works.SecondProgram is null. Can someone verify this ?

This is not part of a real program. I had this issue when I work with Test cases with NMemory and Effort.