Ask a questionAsk a question
 

AnswerCreateSourceQuery with LazyLoadingEnabled and no option to set IsLoaded = true

  • Thursday, October 01, 2009 6:37 PMzeeshan hirani Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Following code illustrates the problem

    using (var db = new CustomContext())

    {

        db.ContextOptions.DeferredLoadingEnabled = true;

        foreach (var worker in db.Workers)

        {

            Console.WriteLine("Worker:{0}", worker.Name);

            var accidents = worker.Accidents.CreateSourceQuery().Where(a => a.Severity == 4);

            worker.Accidents.Attach(accidents);

            foreach (var acc in worker.Accidents)

            {

                Console.WriteLine("  Accident:{0} Severity:{1}", acc.Description, acc.Severity);

            }

        }

    }

    Since lazy loading is enabled as soon as i do for reach on my worker.Accidents, it goes and makes a request to the database, although i have attached only the accidents that i really want loaded. I guess somehow i need to set IsLoaded = true on Accidents but don't know how. Prior it was not a problem but cuz lazingfeature was not available but since this feature is offered there has to be some way to set IsLoaded to true.

    Zeeshan

Answers

  • Thursday, October 15, 2009 7:03 AMDiego B VegaMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    Zeeshan,

    I personally think that the suggestion of making the IsLoaded flag writable to prevent the stack from trying to lazy load the full relationship (i.e. because you have already loaded what you want) is a very interesting insight. Unfortunately, it is very unlikely that we will make a change in these lines for EF 4. Also, in the long term, I would like us to add support for some mechanism to declare a filter that has to be applied when loading the relationship.

    Thanks,
    Diego

    PS: in the code above, I think that the call to Attach should be unnecessary. Have you verified this?


    This posting is provided "AS IS" with no warranties, and confers no rights.
  • Thursday, October 15, 2009 7:11 PMzeeshan hirani Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    I think then the current implementation should be this

    using (var db = new CustomContext())

    {

        db.ContextOptions.LazyLoadingEnabled = false;

        foreach (var worker in db.Workers)

        {

            Console.WriteLine("Worker:{0}", worker.Name);

            worker.Accidents.CreateSourceQuery().Where(a => a.Severity == 4).ToList();

            foreach (var acc in worker.Accidents)

            {

                Console.WriteLine("  Accident:{0} Severity:{1}", acc.Description, acc.Severity);

            }

        }

    }

All Replies

  • Friday, October 02, 2009 5:02 PMNoam Ben-Ami - MSFTMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    If you just set deffered loading to false, the above code should work correctly, no? Why do you turn deffered load on in the above code?


    This posting is provided "AS IS" with no warranties, and confers no rights.
  • Friday, October 02, 2009 7:05 PMzeeshan hirani Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    well first of all I don't need this

    db.ContextOptions.DeferredLoadingEnabled = true

    cuz LazyLoadingEnabled will be set to true by default in .net 4.0 project. so i guess most people would use the default option. so if it is turned on then u will always incur a database hit when you access the related collection even though you have manually attached items to the collection. When lazy loading is enabled you defeat the purpose of manually attaching collections cuz regardless of what you do it will always hit the database. but if i had the option to set IsLoaded to true, it won't happen.

    yes it works fine when LazyLoadingEnanbled is set to false.

    Zeeshan
  • Wednesday, October 14, 2009 6:00 PMzeeshan hirani Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    I am still not clear on how to do this correctly. the option to turn off lazy loading to true and false back and forth does not really look clean. There should be a way to set IsLoaded to true manually.

    Zeeshan
  • Thursday, October 15, 2009 7:03 AMDiego B VegaMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    Zeeshan,

    I personally think that the suggestion of making the IsLoaded flag writable to prevent the stack from trying to lazy load the full relationship (i.e. because you have already loaded what you want) is a very interesting insight. Unfortunately, it is very unlikely that we will make a change in these lines for EF 4. Also, in the long term, I would like us to add support for some mechanism to declare a filter that has to be applied when loading the relationship.

    Thanks,
    Diego

    PS: in the code above, I think that the call to Attach should be unnecessary. Have you verified this?


    This posting is provided "AS IS" with no warranties, and confers no rights.
  • Thursday, October 15, 2009 7:11 PMzeeshan hirani Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    I think then the current implementation should be this

    using (var db = new CustomContext())

    {

        db.ContextOptions.LazyLoadingEnabled = false;

        foreach (var worker in db.Workers)

        {

            Console.WriteLine("Worker:{0}", worker.Name);

            worker.Accidents.CreateSourceQuery().Where(a => a.Severity == 4).ToList();

            foreach (var acc in worker.Accidents)

            {

                Console.WriteLine("  Accident:{0} Severity:{1}", acc.Description, acc.Severity);

            }

        }

    }