0

I am using Entity Framework with Code First to persist my data.

There is a class with a nested list:

public class AgeGroup
{
    public BindingList<WeightGroup> WeightGroups { get; set; }
}

The database context consists of

public DbSet<AgeGroup> AgeGroups { get; set; }

I am creating a window, where the user can modify AgeGroups and their according WeightGroups. In order to bind a ListBox's ItemsSource property to the AgeGroups, I load them and bind to the Local set:

ctx.AgeGroups.Load();
vm.AgeGroups = ctx.AgeGroups.Local;

Up to here, the WeightGroups are not loaded, because they are not needed. So far, so good.

When the user chooses an AgeGroup for modification, its WeightGroups have to be loaded. Up to now I do it like this (in the setter of the SelectedAgeGroup property):

value.WeightGroups = (from age in ctx.AgeGroups
                      where age.Id == value.Id
                      select age.WeightGroups).Single();

However, this seems a bit clumsy. First of all, because a new list is set instead of filling the existing one. Furthermore, there are some behaviours, which are unwanted. This includes e.g. the following:

  • If a WeightGroup is modified and SaveChanges() is called, the old group is still there and additionally a new one with the modified values.
  • If the user removes an entity with SelectedAgeGroup.WeightGroups.Remove(...) and SaveChanges(), the deleted rows are still there.

I assume, the reload of weight groups as listed above is causing this.

How would correct Lazy Loading look like in this case? Ideally, the necessary WeightGroups are loaded automatically by the framework. I read about using an IQueryable instead of BindingList for the WeightGroups property. But this interface does not have methods for inserting and removing entities. Furthermore, if I just exchange the types, not even the AgeGroups are loaded at all.

1 Answer 1

1

You should be able to solve this by making the WeightGroups virtual, at least if you're using EF 4.1 or higher...

public class AgeGroup
{
    public virtual BindingList<WeightGroup> WeightGroups { get; set; }
}

You would also have to include a DbSet in the context...

public DbSet<WeightGroup> WeightGroups { get; set; }

Then it will be automatically loaded when you touch the property, for instance to display it in a list.

Sign up to request clarification or add additional context in comments.

2 Comments

Perfect, thanks. Can you explain, why the List has to be virtual? Btw, it also works without the additional DbSet<>.
What EF does in this case is to create a subclass of your AgeGroup class and implement the lazy loading in the WeightGroups getter. Quite brilliant, since your code always can assume that the WeightGroups are available, but if you don't touch the property in some scenarios they don't get loaded then.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.