ViewModel对象转换为实体框架对象
本文关键字:对象 框架 实体 转换 ViewModel | 更新日期: 2023-09-27 18:26:26
目标:通过实体框架保存ViewModel对象。我有一个具有UnitViewModel
列表的UserViewModel
对象。然后,我有一个UserAdapter
类,它将UserViewModel
转换为实体框架User
对象(请参阅下面的Convert()
)。
现在,我的问题是如何将UnitViewModel
的列表转换为相应的实体框架Unit
列表?-我是否必须通过调用类似context.Units.Where(u=>myListofUnitIDs.Contains(u.UnitID))
的东西来从DB上下文中获取每个对象?
public class UserViewModel
{
public Guid? UserID { get; set; }
public string UserName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Password { get; set; }
public DateTime? CreateTime { get; set; }
public List<UnitViewModel> UserUnits { get; set; }
}
public class UnitViewModel
{
public Guid UnitID { get; set; }
public string Name { get; set; }
public int? SortIndex { get; set; }
public DateTime CreateTime { get; set; }
public bool Assigned { get; set; }
}
public class UserAdapter
{
public static User Convert(UserViewModel userView)
{
User user;
if (userView.UserID.HasValue)
{
using (var provider = new CoinsDB.UsersProvider())
{
user = provider.GetUser(userView.UserID.Value);
}
}
else
{
user = new User();
}
user.FirstName = userView.FirstName;
user.LastName = user.LastName;
user.Password = StringHelper.GetSHA1(userView.Password);
user.UserName = user.UserName;
user.CreateTime = DateTime.Now;
// Problem here :)
// user.Units = userView.UserUnits;
return user;
}
}
UPDATE:这里的主要问题是,我必须从数据库中检索每个Unit
,以将其与ViewModel.Unit
对象匹配(或映射),对吗?我能避开它吗?
请参阅,此操作主要称为映射。因此,您需要将视图模型对象映射到实体对象。
为此,您可以使用已经存在的第三方库作为AutoMapper
。它将通过具有相同名称的反射来映射属性。此外,您还可以使用After
方法添加自定义逻辑。但是,这种方法也有一些优点和缺点。意识到这些缺点可以帮助您决定是否必须使用此API。因此,我建议您阅读一些关于AutoMapper
的优点和缺点的文章,特别是在将实体转换为其他模型时。其中一个缺点是,将来更改视图模型中某个属性的名称可能会出现问题,AutoMapper
将不再处理此问题,您也不会收到任何警告。
foreach(var item in userView.UserUnits)
{
// get the mapped instance of UnitViewModel as Unit
var userUnit = Mapper.Map<UnitViewModel, UserUnit>(item);
user.Units.Add(userUnit);
}
因此,我建议您编写自定义映射程序例如,我为此创建了一个自定义库,它映射了类似以下的对象:
user.Units = userView.UserUnits
.Select(userUnitViewModel => userUnitViewModel.MapTo<UserUnit>())
.ToList();
我将这些映射功能实现为:
public class UserUnitMapper:
IMapToNew<UnitViewModel, UserUnit>
{
public UnitViewModel Map(UserUnit source)
{
return new UnitViewModel
{
Name = source.Name,
...
};
}
}
然后在运行时,我检测将在映射过程中使用的对象的类型,然后调用Map
方法。通过这种方式,您的映射器将与您的操作方法分离。但是,如果你急需它,你当然可以使用这个:
foreach(var item in userView.UserUnits)
{
// get the mapped instance of UnitViewModel as Unit
var userUnit= new UserUnit()
{
Name = item.Name,
...
};
user.Units.Add(userUnit);
}