简体   繁体   中英

Asp.Net MVC - Inserting multiple rows in Database

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 input s 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.

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