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对象匹配(或映射),对吗?我能避开它吗?

ViewModel对象转换为实体框架对象

请参阅,此操作主要称为映射。因此,您需要将视图模型对象映射到实体对象。

为此,您可以使用已经存在的第三方库作为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);
}