voon
voon

Reputation: 773

WPF / MVVM / EF - How to bind to an entity's related entities?

I have a detail view corresponding to a user entity. Each user entity has one or more comment entities, which is represented on the detail view as a grid.

Detail view with grid

So following EF convention, the user model has a UserComments member to represent the relation:

public partial class User
{
    public int UserID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public virtual ICollection<UserComments> UserComments { get; set; }
    //....
}

When it came time to create the user comments grid in the user detail view, I realized that the grid does not properly bind to an ICollection (couldn't add new rows to the grid). After some digging, I found that I needed to use an ObservervableColletion. Ok, so I converted my ICollection into an ObserverableCollection....

public class UserDetailViewModel
{

    public virtual User UserData { get; set; }  
    private ObservableCollection<UserComments> _UserComments;   

    public ObservableCollection<UserComment> UserComments {
        get { return _UserComments; }
    }

    public void Load(int UserID)
    {
        this.UserData = UserRepo.Find(UserID);      
        this._UserComments = new ObservableCollection<UserComment>(UserData.UserComments);
    }

}

Cool. I can add rows to the grid now. But...

At this point, I've realized I've lost EF change tracking by converting User.UserComments to an ObservableCollection and have no easy way of getting the modifed/new comments back into EF.

So have I approached this all wrong? Is there a better way of updating the related data?

Upvotes: 0

Views: 1147

Answers (1)

jjj
jjj

Reputation: 4997

In order for EF to track collection changes, you need to be adding and removing from the collection in the model itself.

this._UserComments = new ObservableCollection<UserComment>(UserData.UserComments);

In the line above, you're creating a collection by copying elements, so when items are added to or removed from UserDetailViewModel.UserComments, those items aren't actually being added to or removed from User.UserComments.


Some options to fix this include:

  • Changing User.UserComments itself to an ObservableCollection and exposing that in the view model. For example:

    public class UserDetailViewModel
    {
        public virtual User UserData { get; set; }     
    
        public ObservableCollection<UserComment> UserComments 
        {
            get { return UserData.UserComments; }
        }
    
        // other stuff...
    }
    
  • Handling add/remove events for UserDetailViewModel.UserComments and modifying the User.UserComments collection there.

This might be helpful as well: https://msdn.microsoft.com/en-us/data/jj574514.aspx

Upvotes: 3

Related Questions