ViewModel对象转换为实体框架对象 [英] ViewModel Object Convert to Entity Framework Object

查看:117
本文介绍了ViewModel对象转换为实体框架对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目标:由Entity Framework保存ViewModel对象。我有 UserViewModel 对象,其中列出了 UnitViewModel 。然后,我有一个 UserAdapter 类,将 UserViewModel 转换为Entity Framework 用户对象(见 Convert()以下如何)。

Goal: to save ViewModel object by Entity Framework. I have UserViewModel object which has list of UnitViewModel. Then, I have a UserAdapter class which converts UserViewModel into Entity Framework User object (see Convert()below how).

现在,我的问题是如何转换这个列表中的 UnitViewModel 到其相应的实体框架单元列表? - 我必须通过调用类似 context.Units.Where(u => myListofUnitIDs.Contains(u.UnitID))?/ p>

Now, my question is how do I convert this list of UnitViewModel to its corresponding Entity Framework Unit list? - Do I have to get each object from DB Context by calling something like context.Units.Where(u=>myListofUnitIDs.Contains(u.UnitID))?

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;
    }
}

更新:主要这里关心的是我必须从数据库中检索每个 Unit ,以匹配(或映射)它与 ViewModel.Unit 对象, 对?可以避免吗?

UPDATE: The main concern here is that I have to retrieve each Unit from database to match (or map) it with ViewModel.Unit objects, right? Can I avoid it?

推荐答案

对于您的信息,此操作主要称为映射。因此,您要将视图模型对象映射到实体对象。

For your information, this operation is called as Mapping mainly. So, you want to map your view model object to the entity object.

为此,您可以使用已存在的第三方库作为 AutoMapper 。它将通过反射映射具有相同名称的属性。此外,您可以使用之后添加您的自定义逻辑方法。但是,这种方法有一些优点和缺点。了解这些缺点可以帮助您决定是否必须使用此API。因此,我建议您阅读有关 AutoMapper 的优点和缺点的一些文章,特别是将实体转换为其他模型。这样的缺点之一是,将来可能会在视图模型中更改一个属性的名称是有问题的,而 AutoMapper 将不再处理,您将不会

For this, you can either use already existed 3rd party library as AutoMapper. It will map properties by reflection which have same name. Also you can add your custom logic with After method. But, this approach has some advantages and disadvantages. Being aware of these disadvantages could help you to decide whether you must use this API or not. So, I suggest you to read some articles about advantages and disadvantages of AutoMapper especially for converting entities to other models. One of such disadvantages is that it can be problem to change the name of one property in the view model in the future, and AutoMapper will not handle this anymore and you won't get any warning about this.

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

因此,我建议您编写自定义的映射器。
例如,我已经为此创建了一个自定义库,它映射了这样的对象:

So, I recommend to write your custom mappers. For example, I have created a custom library for this and it maps objects lik this:

 user.Units = userView.UserUnits
       .Select(userUnitViewModel => userUnitViewModel.MapTo<UserUnit>())
       .ToList();

我正在将这些映射函数实现为:

And I am implementing these mapping functions as:

 public class UserUnitMapper:
        IMapToNew<UnitViewModel, UserUnit>
    {
        public UnitViewModel Map(UserUnit source)
        {
            return new UnitViewModel
            {
                Name = source.Name,
                ...
            };
        }
    }

然后在运行时,我检测到在映射期间将使用的对象,然后调用 Map 方法。这样,您的映射器将与您的操作方法分开。但是,如果您想要紧急,当然可以使用这个:

And then in runtime, I am detecting the types of the objects which will be used during mapping, and then call the Map method. In this way, your mappers will be seperated from your action methods. But, if you want it urgently, of course you can use this:

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

这篇关于ViewModel对象转换为实体框架对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆