If I have lazy loading set to false (for now) then does it matter if I include the "virtual" keyword or leave it out?

StackOverflow https://stackoverflow.com/questions/22744518

Question

It's my understanding that if I want to use lazy loading in my EF6 application I should code my relationships like this with the last two items marked as virtual:

public class Test
{
    public int TestId { get; set; }
    public int ExamId { get; set; }
    public string Title { get; set; }
    public int Status { get; set; }
    public System.DateTime CreatedDate { get; set; }
    public virtual Exam Exam { get; set; }
    public virtual ICollection<UserTest> UserTests { get; set; }
}

If I do not want to use lazy loading (at the moment) and if I set the lazyloading configuration to false then are there any performance considerations if I leave in the virtual keyword or should I code my class like this without the keyword ?

public class Test
{
    public int TestId { get; set; }
    public int ExamId { get; set; }
    public string Title { get; set; }
    public int Status { get; set; }
    public System.DateTime CreatedDate { get; set; }
    public Exam Exam { get; set; }
    public ICollection<UserTest> UserTests { get; set; }
}

The reason I am asking this is I would like to maintain flexibility by keeping in the virtual keyword but only if that will not cause any problems for me when I am not using lazy loading.

I read the following

"if you use the virtual keyword on an ICollection/one-to-many relationship property, it will be lazy-loaded by default, whereas if you leave the virtual keyword out, it will be eager-loaded."

Is this true even if I set DbContext.Configuration.LazyLoadingEnabled = false; ?

Was it helpful?

Solution

The virtual keyword just makes it possible that a derived class can be created dynamically at runtime which overrides the properties that are marked as virtual in order to inject some data access code ("proxy"). But when you set LazyLoadingEnabled = false you tell Entity Framework "Don't override my entity class with a lazy loading proxy". In that case the virtual keyword doesn't have any effect. (Well, I can't actually tell what are the costs of instantiating an object that has virtual properties or methods from .NET CLR viewpoint. It probably has some costs, but I'm sure it's almost nothing compared to actually accessing the database.)

So, your approach to mark properties as virtual to be open for possible lazy loading in the future is fine in my opinion.

BTW: This - whereas if you leave the virtual keyword out, it will be eager-loaded - is wrong. If you disable lazy loading - either by omitting the virtual keyword or by setting LazyLoadingEnable = false - you don't get eager loading by default. Instead you get no loading (of navigation properties) at all. Eager loading must be coded explicitly by using Include or by using projections.

Just to mention it: You can also add the virtual modifier later when you need it. And you can limit it to specific entities. EF doesn't consider this as a model change which would touch somehow the database schema.

OTHER TIPS

When you set LazyLoadingEnabled = False . It will not affect to lazy loading even you include virtual keyword.

virtual works together with two properties of DbContext.Configuration :

  • ProxyCreationEnabled

[MSDN] Gets or sets a value indicating whether or not the framework will create instances of dynamically generated proxy classes whenever it creates an instance of an entity type

  • LazyLoadingEnabled
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top