查看模型虚拟属性和下拉列表

Mik*_*Coy 1 c# asp.net-mvc entity-framework

我无法掌握创建视图模型的正确方法并使用Entity Framework将信息保存回数据库,我似乎无法找到我正在寻找的信息,所以如果我忽略了它,请原谅我.

我在这里发现了这篇文章,他似乎在问同样的问题,但没有得到答案.

我的主要问题是,

对于编辑来说,如果我有一个ProductModel model,有一个Warranty model关系,我应该用virtual property Warranty在视图模型或我应该使用int WarrantyId?

如果我应该使用虚拟属性,为什么这段代码没有Warranty正确保存?

我是否需要明确标记或填写保修以进行更新?

请注意,这不会填充我的编辑视图并按预期选择列表.

我的(简化)代码设置如下:

模型:

    public int ModelId{ get; set; }

    public int ModelNumber { get; set; }

    public virtual Warranty Warranty { get; set;}
Run Code Online (Sandbox Code Playgroud)

查看型号:

    public int ModelId { get; set; }

    [Required(ErrorMessage = "Model Number required")]
    [StringLength(25, ErrorMessage = "Must be under 25 characters")]
    [Display(Name="Model Number")]
    public string ModelNumber { get; set; }

    //related objects and necesary properties
    public virtual Warranty Warranty { get; set; }

    public IEnumerable<SelectListItem> WarrantySelectListItems { get; set; }
Run Code Online (Sandbox Code Playgroud)

控制器(GET):

public ActionResult Edit(int? id)
    {
        //check the id
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }

        //get the model and make sure the object is populated
        var model = _modelService.GetModel(id.Value);
        if (model == null)
        {
            return HttpNotFound();
        }

        //pass our entity (db) model to our view model
        var editModelModel = new EditModelModel();
        editModelModel.InjectFrom(model);

        //warranty select list
        editModelModel.WarrantySelectListItems = WarrantySelectList(editModelModel.Warranty.WarrantyId);

        //option multi select list
        editModelModel.OptionSelectListItems = OptionSelectList();

        return View(editModelModel);
    }
Run Code Online (Sandbox Code Playgroud)

控制器(POST)(正在进行中):

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit(EditModelModel editModelModel)
    {
        if (!ModelState.IsValid)
        {
            return View(editModelModel);
        }

        var modelEntity = new Model();
        modelEntity.InjectFrom(editModelModel);

        _modelService.Update(modelEntity);
        _unitOfWork.Save();

        return RedirectToAction("Index");
    }
Run Code Online (Sandbox Code Playgroud)

查看(简化):

<div class="form-group">
        @Html.Label("Warranty", new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownListFor(x => x.Warranty.WarrantyId, Model.WarrantySelectListItems, "--Select--")
            @Html.ValidationMessageFor(model => model.Warranty.WarrantyId)
        </div>
    </div>
Run Code Online (Sandbox Code Playgroud)

同样,我只想知道设置这些视图模型和模型的正确/最佳方式,以便EF尽可能多地完成工作.我觉得如果我必须创建一个WarrantyId字段,我做错了,但也许情况并非如此.

提前致谢.非常感谢任何见解/帮助.

Lin*_*Lin 5

出于编辑目的,如果我有一个具有保修模型关系的ProductModel模型,我应该在视图模型中使用虚拟财产保修还是我应该使用int WarrantyId?

您不使用virtual关键字作为您的属性ViewModel,因为ViewModel它与Entity Framework无关.使用该virtual关键字的原因是允许在Entity Framework中进行延迟加载.在您的情况下,如果您virtual在Product POCO类中添加Warranty导航属性的关键字,则可以访问以下Warranty属性:

Model.Warranty.WarrantyId
Run Code Online (Sandbox Code Playgroud)

并且它没有将保修信息保存到您的数据库中的原因是您需要在Product类中定义Warranty外键属性.

在您的情况下,如果您使用代码优先方法而产品是您的POCO类,请保持简单如下:

    public class Product
    {
        public int ModelId { get; set; }
        public int ModelNumber { get; set; }
        public int WarrantyId {get;set;}

        [ForeignKey("WarrantyId ")]
        public virtual Warranty Warranty { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

然后你的ViewModel:

    public class MyViewModel 
    {
        public Product Product { get; set; }
        public IEnumerable<SelectListItem> WarrantySelectListItems { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

最后你的看法

  @model MyViewModel

  @Html.DropDownList("Product.Warranty.WarrantyId", Model.WarrantySelectListItems, "--Select--")
  @Html.ValidationMessageFor("Product.Warranty.WarrantyId")
Run Code Online (Sandbox Code Playgroud)

当然,您需要更改操作方法以满足ViewModel.