There are two almost identical situations. In the first, the DbContext context is created as a field, gets all the data from the database, and this sheet binds to the DataGrid and everything works. In the second context, DbContext is created via using , and then everything is the same, but the data that are marked as virtual in the DataGrid not displayed. Why is that ?

UPDATE. Data not marked as virtual also not displayed.

UPDATE 2 If you start the application in debug mode from the ShowData method, and wait a couple of seconds, the data is displayed as it should. If you run fast according to the debugging method, then everything is the same.

UPDATE 3. The problem is still relevant, I want to understand why.

Situation 1.

 class MainVM:BaseVM { ContentStorage db = new ContentStorage(); public MainVM() { ShowData(); } private List<Storage> listStorage; public List<Storage> ListStorage { get { return listStorage; } set { listStorage = value; OnPropertyChanged(); } } private void ShowData() { var s = db.Storages.ToList(); ListStorage = s; } public MainVM() { ShowData(); } } 

Situation 2.

  class MainVM:BaseVM { private List<Storage> listStorage; public List<Storage> ListStorage { get { return listStorage; } set { listStorage = value; OnPropertyChanged(); } } private void ShowData() { using (var db = new ContentStorage()) { var s = db.Storages.ToList(); ListStorage = s; } } public MainVM() { ShowData(); } } 
  • Look at the type of objects - is it exactly your Storage or are there any proxy objects? - Monk
  • @Monk, The type of objects is Storage . - Lightness
  • The problem is essentially that you use Binding to model objects. So do not. - VladD
  • @VladD, and how should I do? - Lightness
  • one
    Well, here ran questions on this topic. The entire list to which the Binding occurs must be read into the VM objects. VM objects must live in a UI thread, in contrast to working with the base, which must be in the background thread (aka brakes). - VladD

1 answer 1

Apparently, "data marked as virtual" is the navigation properties.

EF does not load related entities by default. Instead, it creates a wrapper class on top of your Storage, overriding the virtual properties so that they will be loaded when they are first accessed. This mechanism is called Lazy Load.

For its operation, the context from which the object was loaded must be alive at the time of accessing the property. In the first example, the context is alive - and everything works. In the second - you destroy it immediately after receiving the list. After the destruction of the context, all such properties will throw an exception (which is most likely eaten by the grid)

You should either keep the context alive, or explicitly load the related entities:

 var s = db.Storages.Include("MyProperty").ToList(); 

Or

 var s = db.Storages.Include(s => s.MyPropery).ToList();