在MVVM中表示数据子集时使用Model或ViewModel

本文关键字:Model ViewModel 子集 MVVM 表示 数据 | 更新日期: 2023-09-27 17:50:44

如果我有一个代表大量数据的复杂模型,并且我只希望显示该模型的精简版本(例如名称,描述),MVVM中的最佳方法是什么?

我能找到的大多数解决方案似乎都假设数据已经存在于内存中,并建议使用只公开所需字段的新ViewModel。

然而,与其从数据库中选择出所有的数据,不如只选择必要的数据。然后我要创建一个新模型来保存这些数据吗?直接选择进入ViewModel是可能的,但感觉是错误的。同样,使用一个新模型来表示相同数据的不同版本也会让人感觉不舒服。

做这件事的公认方法是什么?

作为一个简单的例子(足够简单的类,我通常不会这样做):

public class User {
    public int UserID {get;set;}
    public string FirstName
    public string LastName
    public int AccessLevelID
    public List<Groups> UserGroups
}

但我只需要:

public class PreviewUser {
    int UserID
    string FirstName
}

在MVVM中表示数据子集时使用Model或ViewModel

您可以创建另一个类型,它是业务类型的子集。通常这被称为

DTO -数据传输对象,它只封装了你需要的东西。因此,数据库只需要查询实体的子集。

 public class UserDto
 {
      public int ID { get;set;}
      public string Name{ get;set;}
 }

其次,如果您需要向显示添加一些ui逻辑,则通常将特定的DTO包装在更具体的ui模型中。

public class UserUI 
{
     UserDTO _userDto;
     UserUI(UserDTO userDto)
     {
         _userDto = userDto;
     }
     public string Name
     {
        get{return IsAfter_21_hours ? "The user as gone home" : _userDto.Name;}
     }
}

UserViewModel将引用UserUI的一个实例

您可以从模型中删除不需要的属性(以略微提高性能),或者您可以创建一个只提供您想要显示的属性的视图模型。

下面是一个例子:

public class UserViewModel
{
    private readonly User _user;
    public UserViewModel(User user)
    {
        _user = user;
    }
    public int UserID
    {
        get { return _user.UserID; }
    }
    public string FirstName
    {
        get { return _user.FirstName; }
    }
}
...
var viewModels = userRepository.GetUsers().Select(user => new UserViewModel(user));

更新:

如果性能对你来说非常重要,你可以使用继承。基类将是数据的小版本,派生类将包含完整的数据。当您只需要从数据库获取一些字段并节省带宽时,可以使用基类。

public class BaseUser
{
    public int UserID { get; set; }
    public string FirstName { get; set; }
}
public class User : BaseUser
{
    public string LastName { get; set; }
    public int AccessLevelID { get; set; }
    public List<Groups> UserGroups { get; set; }
}

您可以使用多种方法:

  • 使用源模型的"完整版本"。由于您正在构建UI,因此用户将只看到您想要显示的内容;
  • 使用视图模型,并将源模型封装到该视图模型中。实现很简单,UI前的数据量有限;
  • 使用视图模型,并从源模型复制数据到该视图模型。实现更复杂(要么从现有模型映射,要么只从数据库加载所需的数据),但视图模型和模型完全解耦。

实际上,这取决于你更适合什么。

注意,通常"视图模型"answers"模型"之间的区别是模糊的。如果模型看起来像这样:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

…和视图模型-像这样:

public class PersonViewModel
{
    public int Id { get; set; }
    public string Name { get; set; }
}

则丢弃此视图模型。虽然没有区别,但您不需要创建额外的类。

我认为您不必创建新的模型类来保存用户数据以供查看。相反,创建一个视图模型类并将模型属性映射到VM。请看下面的例子

public class UserViewModel
{
    Public UserViewModel(User user)
    {
       //initialize required viewmodel properties here
    }
    int UserID {get;set;}
    string FirstName{get;set;}
}