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

时间:2015-12-11 07:31:35

标签: c# asp.net-mvc entity-framework

目标:按实体框架保存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个对象,对吗?我可以避免吗?

1 个答案:

答案 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);
}