目标:按实体框架保存ViewModel对象。我有UserViewModel
对象,其中包含UnitViewModel
列表。然后,我有一个UserAdapter
类,将UserViewModel
转换为实体框架User
对象(请参阅下面的Convert()
)。
现在,我的问题是如何将此UnitViewModel
列表转换为相应的实体框架Unit
列表? - 我是否必须通过调用类似context.Units.Where(u=>myListofUnitIDs.Contains(u.UnitID))
的内容来获取DB Context中的每个对象?
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
个对象,对吗?我可以避免吗?
答案 0 :(得分:2)
有关您的信息,此操作主要称为 Mapping 。因此,您希望将视图模型对象映射到实体对象。
为此,您可以将已存在的第三方库用作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);
}