ASP .Net MVC 5 How to create list in Create View? One to many relation in EntityFramework

Viewed 517

I want to be able to have list for my model which in Create view could be edited. It would be one to many relation. For example: If I had Client model with possibility of creating shopping list for this person, but list would has it's properties too :

public class Client 
{
public int ClientID {get; set}
public string Name {get; set;}
public virtual ICollection<Product> Product {get; set;}
}

public class Product 
{
public int ProductID {get; set;}
public int ClientID {get; set;}
public string ProductName {get; set;}
public string Description {get; set;}
public virtual Client Client {get; set;}
}

In create view for Client I want to give him name and be able to add products without any limit and after I would have Client with list of products - save him. And of course then I want to be able to view Client with list of products in Details view.

What would be the best approach for this? Please advise :)

1 Answers

The best approach is the entity framework and the codefirst method, which I introduced in the example below. Only I made a small change in the Client class and changed the Product to Products.

public class Client 
{
   public Client()
   {
      Products = new List<Product>();
   }
   public string Name {get; set;}
   public virtual ICollection<Product> Products {get; set;}
}

Add Data In DataBase

Client client = new Client();
client.Name = "Client 1";


Product product1 = new Product() { Description = "desc 1", ProductName = "product 1" };
Product product2 = new Product() { Description = "desc 2", ProductName = "product 2" };
Product product3 = new Product() { Description = "desc 3", ProductName = "product 3" };

client.Products.Add(product1);
client.Products.Add(product2);
client.Products.Add(product3);
db.Clients.Add(client);
db.SaveChanges();

Real Example

Just me in this example add the data to the controller in the database which you have to do in the Repository layer.

Your Model

public class Client
{
   [Key]
   [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
   public int ID { get; set; }
   public string Name { get; set; }
   public virtual ICollection<Product> Products { get; set; }
}

public class Product
{
   [Key]
   [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
   public int ID { get; set; }
   public string ProductName { get; set; }
   public string Description { get; set; }
   public virtual Client Client { get; set; }
}

Tour Context

class yourContextName : DbContext
{
     public yourContextName() : base("yourConnectionName")
     {
     }

    
     protected override void OnModelCreating(DbModelBuilder modelBuilder)
     {
         base.OnModelCreating(modelBuilder);
         modelBuilder.Entity<Client>().Property(c => c.ID)
        .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
         modelBuilder.Entity<Product>().Property(c => c.ID)
        .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
     }
     public DbSet<Client> Clients
     {
         get;
         set;
     }

     public DbSet<Product> Products
     {
         get;
         set;
     }
}

Your Controller

[HttpGet]
public ActionResult AddProduct()
{
    var client = new Client();
    client.Name = "Client 1";
    return View(client);
}
[HttpPost]
public ActionResult AddProduct(Client client, string[] ProductNames, string[] Descriptions)
{
    client.Products = new List<Product>();
    for(int i=0;i<ProductNames.Length;i++)
    {
         if(!string.IsNullOrEmpty(ProductNames[i]))
         {
             Product product = new Product() { Description = 
             Descriptions[i], ProductName = ProductNames[i] };
             client.Products.Add(product);
         }
     }
    //add data to database
    db.Clients.Add(client);
    db.SaveChanges();

    
    return View(client);
}

Your View

@model StackOverFlowMVC.Controllers.Client

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

<h2>AddProduct</h2>
@using (Html.BeginForm("AddProduct", "Home", FormMethod.Post, new { id = "myform" }))
{
    <label>Client Name : </label>
    @Html.TextBoxFor(model => model.Name)
    <br />
    <hr />
    <br />
    <div id="prItems">
        <section id="row1" num="1">
            <div style="margin:10px;">
                <label>Product Name 1 : </label>
                @Html.TextBox("ProductNames",null)
            </div>
            <div style="margin:10px;">
                <label>Product Descr 1 : </label>
                @Html.TextBox("Descriptions", null)
            </div>
            <input type="button" class="RowDelete" value="-" onclick="removeRow(1)" />
            <hr />
        </section>
    </div>
    <button id="btnAddRow">Add Product</button>
    <input type="submit" value="submit" id="btnsubmit" />
}

@section scripts{
    <script>
        $(document).ready(function () {
            $('#ProductNames').val('');
            $('#Descriptions').val('');
        });
        $('#btnAddRow').click(function (e) {
            e.preventDefault();
            var row = "<section><div style = 'margin:10px;'><label></label><input type='text'></div><div style='margin:10px;'><label></label><input type='text'></div><input type='button' class='RowDelete' value='-'/><hr /></section>";
            $('#prItems').append(row);
            orderRow();
        })


        function removeRow(num) {
            $('#prItems section').each(function (idx) {
                if ($(this).attr('num') == num) {
                    $(this).remove();
                }
            });
            orderRow();
        }
        function orderRow() {
            var rowCount = $('#prItems section').length;
            if (rowCount > 0) {
                $('#prItems section').each(function (idx) {
                    var num = idx + 1;
                    $(this).attr('id', 'row' + num);
                    $(this).attr('num', num);

                    $(this).children().children().nextAll().slice(0, 1).prev().text('Product Name ' + num + " : ");
                    $(this).children().children().nextAll().slice(0, 1).attr('name', 'ProductNames');


                    $(this).children().next().children().nextAll().slice(0, 1).prev().text('Product Descr ' + num + " : ");
                    $(this).children().next().children().nextAll().slice(0, 1).attr('name', 'Descriptions');

                
                    $(this).children().next().next().slice(0, 1).attr('onclick', 'removeRow(' + num + ')');
                });
            }
        }
    </script>
}
Related