在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
}
您可以创建另一个类型,它是业务类型的子集。通常这被称为
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;}
}