简体   繁体   中英

ASP.NET MVC: How to use linq lambda expression with a ViewModel to get data?

How to use a linq expression to use a ViewModel to get data from from one of it's domain models? When I try to get the inv_mast_uid that is associated to the item_id the user enters, I only get a 0 and not a unique integer like 10345. I do get all other necessary data from the ViewModel.

Here is an imaging showing my three tables: 在此处输入图片说明

Here is my attempt to create a ViewModel to be used to add new alternate codes to items:

public class AlternateCodeViewModel
{


    [Key]
    [Column(Order = 0)]
    public int inv_mast_uid { get; set; }

    [Key]
    [Column(Order = 1)]
    [StringLength(50)]
    [Display(Name = "Alternate Code")]
    public string Alternate_Code_Item_ID { get; set; }

    [Key]
    [Column(Order = 2)]
    public int Alternate_Code_Brand_ID { get; set; }

    [Required]
    [StringLength(1)]
    [Display(Name = "Exact Flag")]
    public string Exact_Flag { get; set; }

    [Required]
    [StringLength(1)]
    [Display(Name = "Delete Flag")]
    public string Delete_Flag { get; set; }

    public string item_id { get; set; }


    public IEnumerable<web2_item_brands> web2_item_brands { get; set; }

    [ForeignKey("inv_mast_uid")]
    public inv_mast inv_mast { get; set; }

    public AlternateCodeViewModel()
    {
        Delete_Flag = "N";
        Exact_Flag = "Y";
    }
}

Here is my controller method:

[HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult AddAltCode(AlternateCodeViewModel avm)
    {
        if (ModelState.IsValid)
        {

            var newCode = new web2_item_alternate_code
            {
                inv_mast_uid = avm.inv_mast_uid,
                Alternate_Code_Item_ID = avm.Alternate_Code_Item_ID,
                Alternate_Code_Brand_ID = avm.Alternate_Code_Brand_ID,
                Delete_Flag = avm.Delete_Flag,
                Exact_Flag = avm.Exact_Flag
            };

            db.web2_item_alternate_code.Add(newCode);
            db.SaveChanges();
            return RedirectToAction("AltCodeIndex");
        }
        return View();
    }

If it helps here is an image showing my newCode object and it's missing inv_mast_uid property:

在此处输入图片说明

EDIT: As suggested, the following additional information has been added

My controller that initializes the view:

ublic ActionResult AddAltCode()
    {    
        ViewBag.brandsdd = new SelectList(db.web2_item_brands.OrderBy(x => x.brand_name), "item_brand_uid", "brand_name");
        return View();
    }

My view:

@using System.Web.Mvc.Html
@using System.Linq;
@model Non_P21_Quote_System_v1._0.ViewModels.AlternateCodeViewModel

@{
    ViewBag.Title = "AddAltCode";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Add Alternate Code</h2>


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

    <div class="form-horizontal">

    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })


    <div class="form-group">
        @Html.LabelFor(model => model.item_id, "Item ID", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.item_id, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.item_id, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.web2_item_brands, "Brand Name", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownList("Alternate_code_brand_id", new SelectList(ViewBag.brandsdd, "Value", "Text") , htmlAttributes: new { @class = "form-control" })
                @*@Html.ValidationMessageFor(model => model.web2_item_brands, "", new { @class = "text-danger" })*@
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Alternate_Code_Item_ID, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Alternate_Code_Item_ID, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Alternate_Code_Item_ID, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Add" class="btn btn-default" />
        </div>
    </div>
</div>

}

An image of my view: 在此处输入图片说明

As I see from your code, you couldn't add "inv_mast_uid" and "inv_mast inv_mast" as integer properties. You need add "inv_mst" and "web2_item_brands" as objects to "web2_alternate_code" and save them separately after populating. This is the same when you wand to read related object and you need call "include".

So the best approach is add those two objects in "web2_alternate_code" and instantiating them with "web2_alternate_code" constructor. After that you could add any data to those object on [HttpPost].

If this is the result of a create operation as it appears to be the model will always return whatever you put in the model.

When you create the model to send to the create view, you must set the property inv_mast_uid at the time of creation.

In addition, the property must be included in the create view even if it is not going to be edited with a Html.HiddenFor<>. Otherwise, whatever goes into the model at the time it is sent to the view will be lost on the return.

The request parameter list will include only those properties you have explicitly indicated in the view like any html form.

The controller interface takes the form fields and tries to match them to the fields in the class indicated. It won't try to match them if the field does not exist on the create view page.

Perhaps including the code that initializes the information sent to the view would help in this case, and a copy of the view itself.

I would also remove the get/set from the IEnumerable in your model so that it will be treated as a field and not a property. It probably doesn't make any difference with Entity Framework, but the get/set properties should reflect only what is actually in the database unless you intend to try to serialize the list.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM