• python
  • javascript
  • reactjs
  • sql
  • c#
  • java
Facebook Twitter Instagram
Devs Fixed
  • python
  • javascript
  • reactjs
  • sql
  • c#
  • java
Devs Fixed
Home » Resolved: Can’t access entity framework relations outside Dbcontext when Lazyloading

Resolved: Can’t access entity framework relations outside Dbcontext when Lazyloading

0
By Isaac Tonny on 17/06/2022 Issue
Share
Facebook Twitter LinkedIn

Question:

I have a asp.net application using entity framework. I have these two models:
and
And a dbcontext class that looks like this:
and then I have a controller that just needs to load all the customers that I have in my database, and their adresses.
For that purpose I have this:
Which I have tried to debug a bit.
The issue is that as soon as I exit my “using” block, all the related adress objects only consist of this error:
Which is because I exited the context.
How do I still get to access the adresses of my customers, even though I exited the Dbcontext, so I can return them to a view

Answer:

My general advice when working with EF is that entities shouldn’t be referenced outside of the scope of their DbContext. You certainly can work with detached entities, but you have to respect that they are provided in an “as-is” state from the moment they leave the scope of the DbContext. For that reason I recommend that anything passed outside of the scope of the DbContext should be a POCO ViewModel or DTO class to avoid confusing whether an entity class is actually a functional, attached entity representing data domain state, or a detached shell.
Option 1: Deal with DTO/ViewModels.
You can alternatively leverage Automapper, set up the desired projection rules and use ProjectTo<CustomerDTO>(config) to replace the use of Select() above.
When leveraging projection, you do not need lazy loading proxies at all. This has arguably become the defacto recommended approach for EF.
The advantages of the projection method are that these DTOs (or ViewModels) cannot be confused with being entities. The issue with detached entities is that where you have methods in your code that might accept entities, these methods might expect to get entities and access members that aren’t loaded. If they are attached and within the scope of a DbContext, those members can be lazy-loaded (not ideal for performance reasons, but functional) however if they are detached you get errors or NullRefExceptions. The other advantage of projection is the payload of data being pulled from the database and sent to the view logic or end consists of just the data needed.
Option 2: Don’t de-scope the DbContext. With projects like ASP.Net MVC web applications, you can leverage an IoC Container to provide dependency injection into your Controllers. In this way you can set up the DbContext to be injected into the constructor with a lifetime scope set to the Request. In this way, for any given request, all services/classes you might call can be managed by the container and have access to the DbContext.
This can be combined with Option 1 to avoid needing to scope a DbContext with each request/action and better facilitate situations where you may want to make multiple calls against the DbContext and ensure the same context instance is used. For IoC containers there are a number of different ones available, and I believe ASP.Net Core comes with a default one, though I personally use and recommend Autofac. It has good documentation and examples on how to wire it up with MVC projects.
Option 3: Eager load everything you’re going to need to reference. The example you provided should actually work, but your real code is likely missing an eager-load (.Include()) for the desired relationship given your example doesn’t attempt to do anything with the Customers collection you load.
If your code does:
This should work as Addresses was eager loaded. However, if you had:
… without the Include(c => c.Address), then it would fail with that error.
With EF Core if you are going to want to return entities outside of the scope of a DbContext and you have lazy loading proxies enabled, you will want to temporarily turn off the proxy creation to avoid proxy errors. In this case anything you don’t eager load will be left #null or default.
This should ensure that EF doesn’t use proxies for the queries in the scope of that DbContext instance which should be avoided whenever you want to pass entities outside of the scope of the DbContext. This can be useful when you know you won’t need the overhead of eager loading every reference. However, it is much better to use projection (Option 1) in this case to avoid future confusion around whether entities might actually have #null data, or merely it wasn’t eager loaded.

If you have better answer, please add a comment about this, thank you!

c# entity-framework
Share. Facebook Twitter LinkedIn

Related Posts

Resolved: Kivy widget hierarchy not behaving as expected

24/03/2023

Resolved: Pandas Groupby Get Values from Previous Group

24/03/2023

Resolved: Can’t access static methods from outside until JavaScript’s static block is over?

24/03/2023

Leave A Reply

© 2023 DEVSFIX.COM

Type above and press Enter to search. Press Esc to cancel.