【问题标题】:Database First EF6 add data to table with Custom ViewModelDatabase First EF6 使用自定义 ViewModel 将数据添加到表中
【发布时间】:2014-05-15 13:37:21
【问题描述】:

我使用 MVC 5.1 和 EF 6.1 数据库第一模型。我不喜欢脚手架创建的视图,因为它使用了所有数据库列。在创建视图中,我只想让用户输入必填字段,所有其他数据都可以通过编辑详细信息视图来添加。我已经创建了一个视图模型来使用,而不是 .edmx 生成的视图模型。视图按预期工作,但是当单击创建操作按钮时,发布操作会因“[NullReferenceException:对象引用未设置为对象的实例。]

Here is my view model

     public class DesktopCreateViewModel 
{

    [Required]
    [Display(Name = "Serial Number")]
    [StringLength(30)]
    public string SERIAL_NUMBER { get; set; }

    public int Model_DesktopId { get; set; }
    public int DeviceType_DesktopId { get; set; }

    [Required]
    [StringLength(50)]
    public string MAC1 { get; set; }

    [Display(Name = "Arrival Date")]
    public DateTime ARRIVAL_DATE { get; set; }

    [Timestamp]
    [Display(Name = "Record Updated")]
    public DateTime RECORD_UPDATED { get; set; }

    public int LocationId { get; set; }
    public int Location_CodeId { get; set; }
    public int MemoryId { get; set; }
    public int MonitorId { get; set; }
    public int PlantId { get; set; }
    public int DepartmentId { get; set; }
    public int Operating_SystemId { get; set; }

    [ForeignKey("DeparmentId")]
    public virtual Department Department { get; set; }

    [ForeignKey("DeviceType_DesktopId")]
    public virtual DeviceType_Desktop DeviceType_Desktop { get; set; }

    [ForeignKey("Location_CodeId")]
    public virtual Location_Code Location_Code { get; set; }

    [ForeignKey("LocationId")]
    public virtual Location Location { get; set; }

    [ForeignKey("MemoryId")]
    public virtual Memory Memory { get; set; }

    [ForeignKey("Model_DesktopId")]
    public virtual Model_Desktop Model_Desktop { get; set; }

    [ForeignKey("MonitorId")]
    public virtual Monitor Monitor { get; set; }

    [ForeignKey("Operating_SystemId")]
    public virtual Operating_System Operating_System { get; set; }

    [ForeignKey("PlantId")]
    public virtual Plant Plant { get; set; }


    public IEnumerable<DesktopCreateViewModel> Create_Desktop { get; set; }

    public virtual ICollection<DesktopCreateViewModel> Desktops { get; set; }


Here is the portion of the controller that fails
     [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(ICollection<DesktopCreateViewModel> desktop)
    {
        if (ModelState.IsValid)
        {
            foreach (var item in desktop)
            {
                db.Entry(desktop).State = EntityState.Added;
            }
            db.SaveChanges();
            return RedirectToAction("Index");
        }

         ViewBag.DepartmentId = new SelectList(db.Departments, "Id", "DEPARTMENT1", desktop.DepartmentId);
         ViewBag.DeviceType_DesktopId = new SelectList(db.DeviceType_Desktop, "Id", "DEVICE_TYPE", desktop.DeviceType_DesktopId);
         ViewBag.Location_CodeId = new SelectList(db.Location_Code, "Id", "LOCATION_CODE1", desktop.Location_CodeId);
         ViewBag.LocationId = new SelectList(db.Locations, "Id", "LOCATION1", desktop.LocationId);
         ViewBag.MemoryId = new SelectList(db.Memories, "Id", "MEMORY1", desktop.MemoryId);
         ViewBag.Model_DesktopId = new SelectList(db.Model_Desktop, "Id", "MODEL", desktop.Model_DesktopId);
         ViewBag.MonitorId = new SelectList(db.Monitors, "Id", "MONITOR1", desktop.MonitorId);
         ViewBag.Operating_SystemId = new SelectList(db.Operating_System, "Id", "OS", desktop.Operating_SystemId);
         ViewBag.PlantId = new SelectList(db.Plants, "Id", "PLANT1", desktop.PlantId); 
        return View(desktop);
    }

这是视图

@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>Desktop</h4>
        <hr />
        @Html.ValidationSummary(true)

        <div class="form-group">
            @Html.LabelFor(model => model.SERIAL_NUMBER, new { @class = "control-label col-md-4" })
            <div class="col-md-8">
                @Html.EditorFor(model => model.SERIAL_NUMBER)
                @Html.ValidationMessageFor(model => model.SERIAL_NUMBER)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Model_DesktopId, "Model", new { @class = "control-label col-md-4" })
            <div class="col-md-8">
                @Html.DropDownList("Model_DesktopId", String.Empty)
                @Html.ValidationMessageFor(model => model.Model_DesktopId)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.DeviceType_DesktopId, "Device Type", new { @class = "control-label col-md-4" })
            <div class="col-md-8">
                @Html.DropDownList("DeviceType_DesktopId", String.Empty)
                @Html.ValidationMessageFor(model => model.DeviceType_DesktopId)
            </div>
        </div>


        <div class="form-group">
            @Html.LabelFor(model => model.MAC1, new { @class = "control-label col-md-4" })
            <div class="col-md-8">
                @Html.EditorFor(model => model.MAC1)
                @Html.ValidationMessageFor(model => model.MAC1)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.ARRIVAL_DATE, new { @class = "control-label col-md-4" })
            <div class="col-md-8">
                @Html.EditorFor(model => model.ARRIVAL_DATE)
                @Html.ValidationMessageFor(model => model.ARRIVAL_DATE)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.RECORD_UPDATED, new { @class = "control-label col-md-4" })
            <div class="col-md-8">
                @Html.EditorFor(model => model.RECORD_UPDATED)
                @Html.ValidationMessageFor(model => model.RECORD_UPDATED)
            </div>
        </div>


        <div class="form-group">
            @Html.LabelFor(model => model.LocationId, "Location", new { @class = "control-label col-md-4" })
            <div class="col-md-8">
                @Html.DropDownList("LocationId", String.Empty)
                @Html.ValidationMessageFor(model => model.LocationId)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Location_CodeId, "Location Code", new { @class = "control-label col-md-4" })
            <div class="col-md-8">
                @Html.DropDownList("Location_CodeId", String.Empty)
                @Html.ValidationMessageFor(model => model.Location_CodeId)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.MemoryId, "Memory", new { @class = "control-label col-md-4" })
            <div class="col-md-8">
                @Html.DropDownList("MemoryId", String.Empty)
                @Html.ValidationMessageFor(model => model.MemoryId)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.MonitorId, "Monitor", new { @class = "control-label col-md-4" })
            <div class="col-md-8">
                @Html.DropDownList("MonitorId", String.Empty)
                @Html.ValidationMessageFor(model => model.MonitorId)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.PlantId, "Plant", new { @class = "control-label col-md-4" })
            <div class="col-md-8">
                @Html.DropDownList("PlantId", String.Empty)
                @Html.ValidationMessageFor(model => model.PlantId)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.DepartmentId, "Department", new { @class = "control-label col-md-4" })
            <div class="col-md-8">
                @Html.DropDownList("DepartmentId", String.Empty)
                @Html.ValidationMessageFor(model => model.DepartmentId)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Operating_SystemId, "Operating System", new { @class = "control-label col-md-4" })
            <div class="col-md-8">
                @Html.DropDownList("Operating_SystemId", String.Empty)
                @Html.ValidationMessageFor(model => model.Operating_SystemId)
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-8 col-md-4">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

【问题讨论】:

  • 您是否尝试过调试它? desktop 是否为空?
  • 是的,它是空的。它没有从视图中获取数据。
  • 你可以发布视图吗?

标签: entity-framework-6 asp.net-mvc-5.1


【解决方案1】:

该操作需要一组视图模型 (ICollection&lt;DesktopCreateViewModel&gt;),但视图仅包含一个。尝试更改为:

public ActionResult Create(DesktopCreateViewModel desktop)

【讨论】:

  • 这是一个完全不同的问题。您正在尝试保存 DesktopsCreateViewModel 但它不是您数据上下文中的实体。实体框架只能与它知道的实体一起工作。通常使用视图模型,您会将其映射到实体并保存。您可以手动执行映射,也可以使用 AutoMapper 之类的工具。
  • OK 进行了更改并将 foreach 循环更改为 db.Desktops.Add(desktop);。这是无效的,所以现在不确定如何将数据添加到数据库中。
  • 您需要将desktopDesktopCreateViewModel)转换为Desktop(数据上下文中的实体)并将其传递给.Add().Entry()
  • 谢谢,只需要弄清楚如何完成它。 AutoMapper 听起来最好,但不清楚如何使用它,所以我想进行更多研究
  • 只需尝试手动执行此操作,以确保在引入 AutoMapper 之前它可以正常工作。 var desktopEntity = new Desktop { desktop.SERIAL_NUMBER, desktop.ARRIVAL_DATE, ... }; db.Desktops.add(desktopEntity);
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-27
  • 2021-01-02
  • 2022-01-06
  • 2017-01-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多