This simple tutorial explains how to CRUD (Create, Retrieve, Update, and Delete) Records from two one-to-many linked tables (Category and Product) and display in a web grid. Data can be searched with multiple search facility, search by id or search by part of name. The Models are created using Entity Framework Database Method.
Software Required
- Visual Studio 2013 or above
- Entity Framework 6.0 (Available with Visual Studio)
- .NET Framework 4.5 or above (Available with Visual Studio)
- SQL Server Database (Available with Visual Studio)
Start Visual Studio and create a new MVC Project as displayed below.
Go to File >> New >> Project. Name the project as ShoppingCart.

Choose project type as MVC, as shown below.
The project is created and opens.
Creating Database File Store.mdf
Right-click on App_Data folder and got to Add >> New Item >> SQL Server Database.
Name it as Store.mdf as displayed below. The Server Explorer window opens. Create two tables "Category" and "Product" and populate them by executing the provided queries below.

Store .mdf Database File is created as shown below. Right click on Store.mdf file - Open

- CREATE TABLE [dbo].[Category] (
- [CategoryId] INT NOT NULL,
- [CategoryName] NVARCHAR (30) NOT NULL,
- [Remark] NVARCHAR (50) NOT NULL,
- PRIMARY KEY CLUSTERED ([CategoryId] ASC)
- );
- INSERT INTO [dbo].[Category] ([CategoryId], [CategoryName], [Remark]) VALUES (1, N'Computer', N'Desktop & Laptopd')
- INSERT INTO [dbo].[Category] ([CategoryId], [CategoryName], [Remark]) VALUES (2, N'Storage', N'Pendrive & HardDisk')
- INSERT INTO [dbo].[Category] ([CategoryId], [CategoryName], [Remark]) VALUES (3, N'Acssories', N'Mouse etc')
- INSERT INTO [dbo].[Category] ([CategoryId], [CategoryName], [Remark]) VALUES (4, N'Digital Camera', N'Digital Camera')
- INSERT INTO [dbo].[Category] ([CategoryId], [CategoryName], [Remark]) VALUES (5, N'Camera Aceesories', N'Camera Acessories')
- CREATE TABLE [dbo].[Product] (
- [ProductId] INT NOT NULL,
- [ProductName] NVARCHAR (30) NOT NULL,
- [Price] DECIMAL (18) NOT NULL,
- [ReorderLevel] INT NOT NULL,
- [CatId] INT NOT NULL,
- PRIMARY KEY CLUSTERED ([ProductId] ASC),
- CONSTRAINT [fk_cat_product_id] FOREIGN KEY ([CatId]) REFERENCES [dbo].[Category] ([CategoryId]) ON DELETE CASCADE
- );
- INSERT INTO [dbo].[Product] ([ProductId], [ProductName], [Price], [ReorderLevel], [CatId]) VALUES (1, N'Lenovo5000', CAST(25500 AS Decimal(18, 0)), 24, 1)
- INSERT INTO [dbo].[Product] ([ProductId], [ProductName], [Price], [ReorderLevel], [CatId]) VALUES (2, N'SanDisk Penrive', CAST(250 AS Decimal(18, 0)), 300, 2)
- INSERT INTO [dbo].[Product] ([ProductId], [ProductName], [Price], [ReorderLevel], [CatId]) VALUES (3, N'sonyharddisk', CAST(3000 AS Decimal(18, 0)), 31, 2)
- INSERT INTO [dbo].[Product] ([ProductId], [ProductName], [Price], [ReorderLevel], [CatId]) VALUES (4, N'Sony Mouse', CAST(350 AS Decimal(18, 0)), 21, 3)
- INSERT INTO [dbo].[Product] ([ProductId], [ProductName], [Price], [ReorderLevel], [CatId]) VALUES (5, N'Sony PenDrive 16GB', CAST(470 AS Decimal(18, 0)), 45, 2)
- INSERT INTO [dbo].[Product] ([ProductId], [ProductName], [Price], [ReorderLevel], [CatId]) VALUES (6, N'Zebronics Mouse', CAST(300 AS Decimal(18, 0)), 54, 3)
- INSERT INTO [dbo].[Product] ([ProductId], [ProductName], [Price], [ReorderLevel], [CatId]) VALUES (7, N'Sony Camera Stand', CAST(2500 AS Decimal(18, 0)), 22, 5)
- INSERT INTO [dbo].[Product] ([ProductId], [ProductName], [Price], [ReorderLevel], [CatId]) VALUES (8, N'Sony Camera Lens', CAST(65000 AS Decimal(18, 0)), 12, 5)
- INSERT INTO [dbo].[Product] ([ProductId], [ProductName], [Price], [ReorderLevel], [CatId]) VALUES (9, N'Canon Camera Lens', CAST(30000 AS Decimal(18, 0)), 20, 5)
Right-click on Tables >> New Query.
Copy and paste the SQL query for creating the Category table as above and execute it by clicking the arrow symbol on the left. The Category table would be created.
Insert the records by executing the INSERT query as displayed below.
Similarly, create the Product table and insert Product records.
Refresh the Tables folder in the Server Explorer window. The newly created 2 tables will be seen.
Entity Framework database models will be created by the Database-First method.
Please click here to go to my article describing how to create models from database tables using the Database-First method.
Code for the CategoryModel Class is given below.
- namespace ShoppingCart.Models
- {
- using System;
- using System.Collections.Generic;
- public partial class Category
- {
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
- public Category()
- {
- this.Products = new HashSet<Product>();
- }
- public int CategoryId { get; set; }
- public string CategoryName { get; set; }
- public string Remark { get; set; }
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
- public virtual ICollection<Product> Products { get; set; }
- }
- }
Code for the Product Model class is mentioned below.
- namespace ShoppingCart.Models
- {
- using System;
- using System.Collections.Generic;
- public partial class Product
- {
- public int ProductId { get; set; }
- public string ProductName { get; set; }
- public decimal Price { get; set; }
- public int ReorderLevel { get; set; }
- public int CatId { get; set; }
- public virtual Category Category { get; set; }
- }
- }
Creating View Model Class (ProductWithCategoryVM)
This class will be created by combining the properties from Category class and Product class respectively. It will be used in the Controller and to create View also.
Right-click on the Models folder and click Add >> Class.
Name it as ProductWithCategoryVM.
Code for the ProductWithCategory View Model Class is as below.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.ComponentModel.DataAnnotations;
- namespace ShoppingCart.Models
- {
- public class ProductWithCategoryVM
- {
- public int ProductId { get; set; }
- public string ProductName { get; set; }
- public decimal Price { get; set; }
- public int ReorderLevel { get; set; }
- public string CategoryName { get; set; }
- public Product Product { get; set; }
- }
- }
Code for the Home Controller class is given below.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.Mvc;
- using System.Data;
- using System.Data.Entity;
- using System.Net;
- using ShoppingCart.Models;
- namespace ShoppingCart.Controllers
- {
- public class HomeController : Controller
- {
- DBContext db = new DBContext();
- public ActionResult Products(string q, string S)
- {
- //Populating Department DropDownList in View
- ViewBag.Categories = new SelectList(db.Categories, "CategoryId", "CategoryName");
- //Searching Record
- int id = Convert.ToInt32(Request["SearchType"]);
- var searchParameter = "Searching";
- var ProductWithCategoryVMlist = (from P in db.Products
- join C in db.Categories on
- P.CatId equals C.CategoryId
- select new ProductWithCategoryVM
- {
- ProductId = P.ProductId,
- ProductName = P.ProductName,
- Price = P.Price,
- ReorderLevel = P.ReorderLevel,
- CategoryName = P.Category.CategoryName
- });
- if (!string.IsNullOrWhiteSpace(q))
- {
- switch (id)
- {
- case 0:
- int iQ = int.Parse(q);
- ProductWithCategoryVMlist = ProductWithCategoryVMlist.Where(p => p.ProductId.Equals(iQ));
- searchParameter += " ProductId for ' " + q + " '";
- break;
- case 1:
- ProductWithCategoryVMlist = ProductWithCategoryVMlist.Where(p => p.ProductName.Contains(q));
- searchParameter += " Product Name for ' " + q + " '";
- break;
- case 2:
- ProductWithCategoryVMlist = ProductWithCategoryVMlist.Where(p => p.CategoryName.Contains(q));
- searchParameter += " Category Name for '" + q + "'";
- break;
- }
- }
- else
- {
- searchParameter += "ALL";
- }
- ViewBag.SearchParameter = searchParameter;
- return View(ProductWithCategoryVMlist.ToList()); //List of Products with Category Name)
- //return View(ProductWithCategoryVMlist); //List of Products with Category Name)
- }
- public ActionResult About()
- {
- ViewBag.Message = "Your application description page.";
- return View();
- }
- [HttpPost]
- public ActionResult Insert()
- {
- try
- {
- string ProductName = Request["txtPName"].ToString();
- int CatId = Convert.ToInt32(Request["Categories"].ToString());
- decimal price = Convert.ToDecimal(Request["txtPrice"].ToString());
- int ReorderLevel = Convert.ToInt32(Request["txtReorderLevel"].ToString());
- int NextId = db.Products.Max(p => (int)p.ProductId) + 1;
- Product NewProduct = new Product();
- NewProduct.ProductId = NextId;
- NewProduct.ProductName = ProductName;
- NewProduct.CatId = CatId;
- NewProduct.Price = price;
- NewProduct.ReorderLevel = ReorderLevel;
- db.Products.Add(NewProduct);
- db.SaveChanges();
- //Sending Data To Products Controller.
- TempData["Message"] = "Record saved successfully";
- }
- catch
- {
- TempData["Message"] = "Error while saving record";
- }
- return RedirectToAction("Products");
- }
- // GET: /Product/Edit/5
- public ActionResult Edit(int? id)
- {
- if (id == null)
- {
- return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
- }
- Product editProduct = db.Products.Find(id);
- //ViewBag.CategoryListItems = db.Categories.Distinct().Select(i => new SelectListItem() { Text = i.CategoryName, Value = i.CategoryId.ToString() }).ToList();
- //Populating Department DropDownList in View
- ViewBag.Categories = new SelectList(db.Categories, "CategoryId", "CategoryName");
- if (editProduct == null)
- {
- return HttpNotFound();
- }
- return View(editProduct);
- }
- // POST: /Product/Edit/5
- // To protect from overposting attacks, please enable the specific properties you want to bind to, for
- // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
- [HttpPost]
- [ValidateAntiForgeryToken]
- public ActionResult Edit([Bind(Include = "ProductId,ProductName,CatId,Price,ReorderLevel")] Product editProduct)
- {
- try
- {
- if (ModelState.IsValid)
- {
- int CatId = Convert.ToInt32(Request["Categories"].ToString());
- editProduct.CatId = CatId;
- db.Entry(editProduct).State = EntityState.Modified;
- db.SaveChanges();
- editProduct = null;
- TempData["Message"] = "Record updated successfully";
- return RedirectToAction("Products");
- }
- }
- catch
- {
- TempData["Message"] = "Error while updating record";
- }
- return RedirectToAction("Products");
- }
- // GET: /Product/Delete/5
- public ActionResult Delete(int? id)
- {
- if (id == null)
- {
- return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
- }
- Product deleteProduct = db.Products.Find(id);
- if (deleteProduct == null)
- {
- return HttpNotFound();
- }
- return View(deleteProduct);
- }
- // POST: /Product/Delete/5
- [HttpPost, ActionName("Delete")]
- [ValidateAntiForgeryToken]
- public ActionResult DeleteConfirmed(int id)
- {
- try
- {
- Product deleteProduct = db.Products.Find(id);
- db.Products.Remove(deleteProduct);
- db.SaveChanges();
- deleteProduct = null;
- TempData["Message"] = "Record Deleted successfully";
- return RedirectToAction("Products");
- }
- catch
- {
- TempData["Message"] = "Error while deleting record";
- }
- return RedirectToAction("Products");
- }
- public ActionResult Contact()
- {
- ViewBag.Message = "Your contact page.";
- return View();
- }
- }
- }
This is the code for the View Products.cshtml page.

vel velPosted Jul 28, 2020, 1:50 AM
Super very useful
DAVID POWELLPosted Dec 18, 2019, 10:16 AM
I keep getting error: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable
Win Thura Kyaw KyawPosted Aug 8, 2019, 10:11 AM
How to get datetime value in insert controller ?