【问题标题】:Cannot convert ViewModel to DataModel无法将 ViewModel 转换为 DataModel
【发布时间】:2021-03-06 11:48:59
【问题描述】:

我为我的用户提供了一个 UserViewModel。我想用它来注册。

我不想使用我的数据模型进行注册或登录。

我的 UserViewModel 如下:

public class UserViewModel
{
    public int    user_id         { get; set; } //Primary Key in user table

    [Required]
    [DisplayName("Email:")]
    public string email           { get; set; }

    [Required]
    [DisplayName("First Name:")]
    public string f_name          { get; set; }

    [Required]
    [DisplayName("Last Name:")]
    public string l_name          { get; set; }

    [Required]
    [DisplayName("Contact Number:")]
    public string contact         { get; set; }

    [Required]
    [DisplayName("Gender:")]
    public string gender          { get; set; }

    [Required]
    [DisplayName("Blood Type:")]
    public string blood_type      { get; set; }

    [Required]
    [DisplayName("Password:")]
    [DataType(DataType.Password)]
    public string password        { get; set; }

    [Required]
    [DisplayName("Confirm Password:")]
    [DataType(DataType.Password)]
    [Compare("password")]
    public string confirm_password { get; set; }
}

我的注册ActionMethod如下:

    [HttpPost]
    public ActionResult Registration(UserViewModel uvmr)
    {
        db.users.Add(uvmr);
        db.SaveChanges();
        return View();
    }

我的用户数据模型(user.cs)如下:

public partial class user
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public user()
    {
        this.appointments = new HashSet<appointment>();
    }

    public int user_id { get; set; }
    public string f_name { get; set; }
    public string l_name { get; set; }
    public string email { get; set; }
    public string contact { get; set; }
    public string gender { get; set; }
    public string blood_type { get; set; }
    public string password { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<appointment> appointments { get; set; }
}

注意:我的用户表中没有确认密码列。

现在错误提示无法从 das.Models.ViewModel.UserViewModel 转换为 das.Models.DataModel.user

这个解决方法是什么?

【问题讨论】:

  • 没有“变通办法”——您需要手动或使用 Automapper 之类的工具将视图模型映射到数据模型的新实例。
  • @TiesonT。你能提供任何手动映射的链接吗?
  • 手动映射:只需创建一个user 对象并将其字段1by1 设置为等于您的uvmr 对象字段

标签: c# asp.net asp.net-mvc-5


【解决方案1】:

您不能只为 db.users.Add(uvmr); 提供任何对象实例 - DbSet&lt;T&gt;.Add() 方法会被键入到您的每个数据模型中。

由于您的模型非常相似,因此将一种模型转换为另一种相对简单:

var newUser = new user
{
    user_id = uvmr.user_id
    f_name = uvmr.f_name 
    l_name = uvmr.l_name 
    email = uvmr.email 
    contact = uvmr.contact 
    gender = uvmr.gender 
    blood_type = uvmr.blood_type 
    password = uvmr.password 
};

然后你可以添加新的user实例:

db.users.Add(newUser);

假设您不想在每次需要将一个映射到另一个时都复制此代码,您可以创建一个映射实用程序 - 我倾向于为此使用静态类:

public static class Mapper
{
    public static user MapUser(UserViewModel uvmr)
    {
        return uvmr == null ? null : new user
        {
            user_id = uvmr.user_id
            f_name = uvmr.f_name 
            l_name = uvmr.l_name 
            email = uvmr.email 
            contact = uvmr.contact 
            gender = uvmr.gender 
            blood_type = uvmr.blood_type 
            password = uvmr.password 
        };
    }
}

然后你可以这样做:

var user = Mapper.MapUser(uvmr);

当然,AutoMapper 之类的实用程序也可以做到这一点,而且在您的情况下可能更简单 - AutoMapper,即使没有任何设置代码,也会尝试映射具有相同名称的属性。

顺便说一句,您的类名和属性目前违反了 Microsoft 的命名约定 - 如果这是要在您的组织外部共享的代码,我建议您阅读 Naming Guidelines

【讨论】:

  • 所以,如果我使用第一种方法,我将不得不在每个操作方法中复制映射,每当我需要在用户表上存储一些东西时?
  • 是的。您唯一的其他选择是实现转换运算符 - docs.microsoft.com/en-us/dotnet/csharp/language-reference/… - 尽管您仍然需要将视图模型转换为数据模型。
猜你喜欢
  • 2021-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-08
  • 2020-11-25
  • 1970-01-01
  • 2011-11-21
  • 1970-01-01
相关资源
最近更新 更多