Declaring navigation property as lazy loading but eager loading it. Bad practice?
All of our navigation properties are defined as virtual (Lazy Loading) but most of them are eager loaded (.Include) is there a performance hit for the flexibility of lazy loading? Should we only lazy load when we truly need it to be lazy loaded?
A quick benchmark (loading thousands of objects in object graphs) shows that there are no markable differences in load time when lazy loading and proxy generation are enabled or disabled.
However, when you know that you do eager loading (and probably use a short-lived context) I would always turn off lazy loading and proxy generation.
context.Configuration.LazyLoadingEnabled = false; context.Configuration.ProxyCreationEnabled = false;
Even though it doesn't noticeably improve performance, at least it removes the risk of triggering a lazy load when the context is out of scope, or a lazy load cascade when objects get serialized.
In your case, when eager loading prevails, you could even make this the default, i.e. turn of these properties in the constructor your context class.
Note that you do gain performance when you fetch objects with AsNoTracking(), which is good practice when you get objects for read-only purposes. This happens quite often: in disconnected settings, e.g. when objects get serialized into a web client, the upload is always read-only, even though the client may be able to modify the objects. The changes are dealt with in the post action.
It depends why you are doing with the objects returned. Lazy loading will cause new queries to get sent to the database when you try to access the navigation property.
If you eager load the object to include all of it's navigation properties and then never use them, they yes. You are requesting more data from the db and then more time has to be spent parsing them. Of course the reverse is true also.
If you get an object from the database and start accessing the navigation properties, you have to query the database for them causing n+1 queries to occur. I would say this is more costly than asking for the records in batch, but it really comes down to you knowing how the object will be used for a particular operation.
Personally, In a web environment, I eager load since the context is short lived. In a desktop environment where you would keep the context alive for the entire applications session, I would use lazy loading as you won't have to build the context over and over for subsequent queries.