WPF / MVVM / EF - 如何绑定到实体的相关实体?

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

我有一个对应于用户实体的详细视图。每个用户实体都有一个或多个评论实体,在详细信息视图中以网格表示。

所以按照 EF 约定,用户模型有一个 UserComments 成员来表示关系:

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; }
    //....
}

在用户详细信息视图中创建用户评论网格时,我意识到网格没有正确绑定到 ICollection(无法向网格添加新行)。经过一番挖掘,我发现我需要使用 ObservervableColletion。好的,所以我将我的 ICollection 转换为 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);
    }

}

酷。我现在可以向网格中添加行。但是...

在这一点上,我意识到我已经通过将 User.UserComments 转换为 ObservableCollection 来丢失 EF 更改跟踪,并且没有简单的方法将 modifed/new 评论返回到 EF。

所以我是不是完全错了?有没有更好的更新相关数据的方法?

为了让 EF 跟踪集合更改,您需要在模型本身的集合中添加和删除集合。

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

在上面的行中,您通过 copying elements 创建了一个集合,因此当项目被添加到 UserDetailViewModel.UserComments 或从中删除时,这些项目实际上并没有被添加到或从中删除User.UserComments.


解决此问题的一些选项包括:

  • User.UserComments 本身更改为 ObservableCollection 并将其公开在视图模型中。例如:

    public class UserDetailViewModel
    {
        public virtual User UserData { get; set; }     
    
        public ObservableCollection<UserComment> UserComments 
        {
            get { return UserData.UserComments; }
        }
    
        // other stuff...
    }
    
  • 处理 UserDetailViewModel.UserComments 的 add/remove 事件并修改那里的 User.UserComments 集合。

这也可能有帮助: https://msdn.microsoft.com/en-us/data/jj574514.aspx