且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Asp.Net MVC - 插入数据库中多行

更新时间:2023-10-07 16:35:46

如果我理解你纠正你在你的视图模型具有的属性列表。

所以,如果你想用它来工作,你应该把它列出。

所以,你应该改变你的视图模型:

  //我把你的列表的所有属性,以单独的模型
公共类AttriduteViewModel
{
    公众诠释ProductColorVariantId {搞定;组; }
    公众诠释ProductSizeVariantId {搞定;组; }
    公众诠释ProductSizeVariantValueId {搞定;组; }
    公众诠释ProductAttributeId {搞定;组; }
    公众诠释ProductAttributeValueId {搞定;组; }
    公众诠释?数量{搞定;组; }
}公共类ProductAttributesViewModel
{
    公共产品产品{搞定;组; }
    公共ProductAttribute ProductAttribute {搞定;组; }
    公共ProductAttributeValue ProductAttributeValue {搞定;组; }
    公众诠释产品编号{搞定;组; }
    公共字符串名称{;组; }
    [AllowHtml]
    公共字符串描述{搞定;组; }
    公共小数?价格{搞定;组; }
    公共字符串大小{搞定;组; }
    公众诠释股票{搞定;组; }
    //注意这条线
    公开名单< AttriduteViewModel> AdditionalAttridutes {搞定;组;}
}

这基本上所有。现在,你应该只为您的 AdditionalAttridutes 右装订。这将是更容易 HtmlHelpers ,使它象 Html.DropDownListFor Html.HiddenFor Html.TextBoxFor 。我只是不能看到它在你的视图。

问题是,如果你创建你的输入 s的助手,他们会马上名称属性和你的模型将正确地绑定在发布即可。

这是你会面对另一件事是动态的在你的例子一样创建新的项目。你应该想想正确的名称属性。我建议你​​检查一下这个问题这个伟大的答案

I'm building an E-Commerce app and now working on ProductAttributes. I want to handle Size and Color and Quantity attribues.

Example T-shirt has multiple colors and sizes with different quantity.

 Name    - Color - Size  - Qty
T-shirtA - Black - Small - 5pc
T-shirtA - Blue - Medium - 10pc
T-shirtA - Blue - Large -  4pc

I want to handle he above scenario.

Tables

1. Product: Product_Id(pk), Name, Price, Description

2. ProductSizes: ProductSize_Id(pk), SizeName

3. ProductSizeValues: ProductSizeValue_Id(pk), ProductSize_Id(fk), Name

4. ProductColors: ProductColor_Id(pk), Name

5. ProductAttribues: ProductAttribute_Id(pk), ProductSize_Id(fk), ProductColor_Id(fk)

6. ProductAttribueValues: ProductAttributeValue_Id(pk), ProductAttribute_Id(fk), Product_Id(fk), ProductSizeValue_Id(fk), ProductColor_Id(fk), Quantity.

First I was confused about how can I store Colors and Sizes with quantity, then I installed OpenCart and saw their DB Schema and no I've above tables.

I've inserted some values directly into the DB and everything is working fine. Getting the desired results. But obviously I want my user to store these details using ViewPage.

I've created a ViewModel

ProductAttributeViewModel.cs

public class ProductAttributesViewModel
{
    public Product Product { get; set; }
    public ProductAttribute ProductAttribute { get; set; }
    public ProductAttributeValue ProductAttributeValue { get; set; }
    public int ProductId { get; set; }
    public string Name { get; set; }
    [AllowHtml]
    public string Description { get; set; }
    public decimal? Price { get; set; }
    public int? Quantity { get; set; }
    public string Sizes { get; set; }
    public int Stock { get; set; }
    public int ProductColorVariantId { get; set; }
    public int ProductSizeVariantId { get; set; }
    public int ProductSizeVariantValueId { get; set; }
    public int ProductAttributeId { get; set; }
    public int ProductAttributeValueId { get; set; }
}

Contoller I have to insert data into mutliple tables. so his is my controller

[HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult AddProduct(ProductAttributesViewModel newRecord)
    {
IEnumerable<SelectListItem> productsizevariants = db.ProductSizeVariants.Select(c => new SelectListItem
        {
            Value = c.ProductSizeVariantId.ToString(),
            Text = c.Name

        });
        ViewBag.ProductSizeVariantId = productsizevariants;

        IEnumerable<SelectListItem> productsizevariantsvalues = db.ProductSizeVariantValues.Select(c => new SelectListItem
        {
            Value = c.ProductSizeVariantValueId.ToString(),
            Text = c.Name

        });
        ViewBag.ProductSizeVariantValueId = productsizevariantsvalues;

        IEnumerable<SelectListItem> productcolorvariantsid = db.ProductColorVariants.Select(c => new SelectListItem
        {
            Value = c.ProductColorVariantId.ToString(),
            Text = c.Name

        });
        ViewBag.ProductColorVariantId = productcolorvariantsid;

                    var product = new Product
                    {
                        Name = newRecord.Name,
                        Description = newRecord.Description,
                        Price = newRecord.Price,
                    };

                    var productattributes = new ProductAttribute
                    {
                        ProductSizeVariantId = newRecord.ProductSizeVariantId,
                        ProductColorVariantId = newRecord.ProductColorVariantId,
                        ProductId = newRecord.ProductId
                    };

                    var productattributevalues = new ProductAttributeValue
                    {
                        ProductAttributeId = newRecord.ProductAttributeId,
                        ProductId = newRecord.ProductId,
                        ProductSizeVariantId = newRecord.ProductSizeVariantId,
                        ProductSizeVariantValueId = newRecord.ProductSizeVariantValueId,
                        ProductColorVariantId = newRecord.ProductColorVariantId,
                        Quantity = newRecord.Stock
                    };

                    db.Products.Add(product);
                    db.ProductAttributes.Add(productattributes);
                    db.ProductAttributeValues.Add(productattributevalues);
                    db.SaveChanges();
                    return RedirectToAction("Index", "Home");
  }

Everything is working great. Data is stored in all tables with foreign keys and all values. Now I want to add dynamic text fields for adding Size and Colors.

I've colors and sizes stored in DB and from controller I'm passing those values in dropdownlist and populating them.

View

@model FypStore.ViewModels.ProductAttributesViewModel

@using (Html.BeginForm("AddProduct", "Store", FormMethod.Post, new { enctype = "multipart/form-data", @class = "form-horizontal col-md-12", role = "form" }))
{
<div class="form-group">
    @Html.LabelFor(m => m.Name, new { @class = "col-md-2 control-label", data_val_required = "required" })
    <div class="col-md-10">
        @Html.TextBoxFor(m => m.Name, new { @class = "form-control" })
        @Html.ValidationMessageFor(m => m.Name)
    </div>
</div>
<div class="form-group">
    @Html.LabelFor(m => m.Description, new { @class = "col-md-2 control-label" })
    <div class="col-md-10">
        @Html.TextAreaFor(m => m.Description, new { @class = "form-control" })
    </div>
</div>
<div class="form-group">
    <div class="row">

         @*@Html.LabelFor(m => m.ProductSizeVariantId, new { @class = "col-md-2 control-label" })*@
        <div class="col-md-2 control-label">

        </div>
            <div class="input_fields_wrap">
                <button class="add_field_button">Add More Fields</button>
                <div class="col-md-2">
                    @Html.DropDownList("ProductSizeVariantId", null, "Size", new { @class = "control-label" })
                </div>
                <div class="col-md-2">
                    @Html.DropDownList("ProductSizeVariantValueId", null, "Select Size", new { @class = "control-label" })
                </div>
                <div class="col-md-2">
                    @Html.DropDownList("ProductColorVariantId", null, "Select Color", new { @class = "control-label" })
                </div>
                <div class="col-md-2">
                    @Html.TextBoxFor(x => x.Stock, new { @placeholder = "Quantity", @class = "form-control" })
                </div>
            </div>
    </div>
</div>
<div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" class="btn btn-default" value="Create Product" />
            </div>
        </div>
        }

Here is the demo what I'm trying to achieve.

$('.multi-field-wrapper').each(function() {
    var $wrapper = $('.multi-fields', this);
    $(".add-field", $(this)).click(function(e) {
        $('.multi-field:first-child', $wrapper).clone(true).appendTo($wrapper).find('input').placeholder('quantity').focus();
    });
    $('.multi-field .remove-field', $wrapper).click(function() {
        if ($('.multi-field', $wrapper).length > 1)
            $(this).parent('.multi-field').remove();
    });
});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form role="form" action="/wohoo" method="POST">
  <input type="text" placeholder="Name" name="name"><br />
  <input type="text" placeholder="Price" name="price"><br />
  <input type="text" placeholder="Description" name="description"><br />
  <label>Attributes</label>
    <div class="multi-field-wrapper">
      <div class="multi-fields">
        <div class="multi-field">
        
        <select>
        <option>Green</option>
        <option>Blue</option>
        <option>Black</option>
        <option>Purple</option>
        <option>White</option>
        </select>
        <select>
        <option>XS</option>
        <option>Small</option>
        <option>Medium</option>
        <option>Large</option>
        <option>XL</option>
        </select>
          <input type="text" placeholder="quantity" name="quantity">
          <button type="button" class="remove-field">Remove</button>
        </div>
      </div>
    <button type="button" class="add-field">Add field</button>
  </div>
     <button type="button">Create Product</button>
</form>

If I understand you correct you have a list of Attributes in your View Model.

So if you want to work with it you should place it to list.

So you should change your View Model:

//I put all properties of your list to separate model
public class AttriduteViewModel
{
    public int ProductColorVariantId { get; set; }
    public int ProductSizeVariantId { get; set; }
    public int ProductSizeVariantValueId { get; set; }
    public int ProductAttributeId { get; set; }
    public int ProductAttributeValueId { get; set; }
    public int? Quantity { get; set; }
}

public class ProductAttributesViewModel
{
    public Product Product { get; set; }
    public ProductAttribute ProductAttribute { get; set; }
    public ProductAttributeValue ProductAttributeValue { get; set; }
    public int ProductId { get; set; }
    public string Name { get; set; }
    [AllowHtml]
    public string Description { get; set; }
    public decimal? Price { get; set; }
    public string Sizes { get; set; }
    public int Stock { get; set; }
    //note this line
    public List<AttriduteViewModel> AdditionalAttridutes {get; set;}
}

That's basically all. Now you should only make right binding for your AdditionalAttridutes. It will be easier to make it with HtmlHelpers like Html.DropDownListFor, Html.HiddenFor and Html.TextBoxFor. I just can't see it in your View.

The thing is if you create your inputs with Helpers they will get right name Attribute and your model will bind correctly on POST.

Another thing that you will face with is dynamically create new Items like in your example. You should think about right name attribute. I advice you to check this great answer about that problem.