π± ASP.NET Core MVC Mobile Shop – Part 3: Models, DbContext, Database Setup & Seeding
π Introduction
Welcome to Part 3 of our Mobile Shop Website using ASP.NET Core MVC series.
In this part, we will build the core foundation of our application, including:
- Creating all required Models
- Configuring ApplicationDbContext
- Setting up ASP.NET Identity
- Implementing Database Seeding (DbInitializer)
- Running Migrations & Database Update
This step transforms our project into a fully structured eCommerce backend system.
π― What You Will Learn
In this tutorial, you will learn:
- How to design real-world eCommerce models
- How to configure DbContext with relationships
- How to integrate Identity with custom user
- How to seed roles and admin user
- How to create and update database
π§± Step 1: Create Models
Create a Models folder and add the following classes:
πΉ ApplicationUser (Extend Identity)
C# / ApplicationUser.cs
using Microsoft.AspNetCore.Identity;
using System.ComponentModel.DataAnnotations;
namespace MobileShop.Models
{
public class ApplicationUser : IdentityUser
{
[Required]
[Display(Name = "First Name")]
[StringLength(50)]
public string FirstName { get; set; } = string.Empty;
[Required]
[Display(Name = "Last Name")]
[StringLength(50)]
public string LastName { get; set; } = string.Empty;
[Display(Name = "Full Name")]
public string FullName => $"{FirstName} {LastName}";
[StringLength(200)]
public string? Address { get; set; }
[StringLength(100)]
public string? City { get; set; }
[StringLength(20)]
public string? PostalCode { get; set; }
[StringLength(50)]
public string? Country { get; set; } = "Pakistan";
[StringLength(255)]
public string? ProfileImageUrl { get; set; }
[DataType(DataType.Date)]
[Display(Name = "Date of Birth")]
public DateTime? DateOfBirth { get; set; }
[Display(Name = "Member Since")]
[DataType(DataType.DateTime)]
public DateTime CreatedAt { get; set; } = DateTime.Now;
public bool IsActive { get; set; } = true;
// Navigation Properties
public virtual ICollection<Order> Orders { get; set; } = new List<Order>();
public virtual ICollection<Review> Reviews { get; set; } = new List<Review>();
public virtual ICollection<WishlistItem> WishlistItems { get; set; } = new List<WishlistItem>();
}
}
πΉ Brand
C# / Brand.cs
using System.ComponentModel.DataAnnotations;
namespace MobileShop.Models
{
public class Brand
{
[Key]
public int Id { get; set; }
[Required]
[StringLength(100)]
[Display(Name = "Brand Name")]
public string Name { get; set; } = string.Empty;
[StringLength(500)]
public string? Description { get; set; }
[StringLength(255)]
[Display(Name = "Logo URL")]
public string? LogoUrl { get; set; }
[StringLength(100)]
public string? Country { get; set; }
[StringLength(255)]
[Display(Name = "Official Website")]
public string? WebsiteUrl { get; set; }
public bool IsActive { get; set; } = true;
[DataType(DataType.DateTime)]
public DateTime CreatedAt { get; set; } = DateTime.Now;
// Navigation Properties
public virtual ICollection<Product> Products { get; set; } = new List<Product>();
}
}
πΉ Category
C# / Category.cs
using System.ComponentModel.DataAnnotations;
namespace MobileShop.Models
{
public class Category
{
[Key]
public int Id { get; set; }
[Required]
[StringLength(100)]
[Display(Name = "Category Name")]
public string Name { get; set; } = string.Empty;
[StringLength(500)]
public string? Description { get; set; }
[StringLength(255)]
[Display(Name = "Image URL")]
public string? ImageUrl { get; set; }
[Display(Name = "Display Order")]
public int DisplayOrder { get; set; }
public bool IsActive { get; set; } = true;
[DataType(DataType.DateTime)]
public DateTime CreatedAt { get; set; } = DateTime.Now;
// Navigation Properties
public virtual ICollection<Product> Products { get; set; } = new List<Product>();
}
}
πΉ Product
C# / Product.cs
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace MobileShop.Models
{
public class Product
{
[Key]
public int Id { get; set; }
[Required]
[StringLength(200)]
[Display(Name = "Product Name")]
public string Name { get; set; } = string.Empty;
[StringLength(100)]
public string? Model { get; set; }
[StringLength(2000)]
public string? Description { get; set; }
[StringLength(1000)]
[Display(Name = "Short Description")]
public string? ShortDescription { get; set; }
[Required]
[Column(TypeName = "decimal(18,2)")]
[Display(Name = "Original Price")]
public decimal OriginalPrice { get; set; }
[Required]
[Column(TypeName = "decimal(18,2)")]
[Display(Name = "Sale Price")]
public decimal SalePrice { get; set; }
[Display(Name = "Discount Percentage")]
public int DiscountPercentage => OriginalPrice > 0
? (int)((OriginalPrice - SalePrice) / OriginalPrice * 100)
: 0;
[Display(Name = "Stock Quantity")]
public int StockQuantity { get; set; } = 0;
[StringLength(255)]
[Display(Name = "Main Image")]
public string? MainImageUrl { get; set; }
public bool IsFeatured { get; set; } = false;
public bool IsNewArrival { get; set; } = false;
public bool IsBestseller { get; set; } = false;
public bool IsActive { get; set; } = true;
// Foreign Keys
[Display(Name = "Category")]
public int CategoryId { get; set; }
[Display(Name = "Brand")]
public int BrandId { get; set; }
// Navigation Properties
[ForeignKey("CategoryId")]
public virtual Category Category { get; set; } = null!;
[ForeignKey("BrandId")]
public virtual Brand Brand { get; set; } = null!;
public virtual ICollection<ProductImage> ProductImages { get; set; } = new List<ProductImage>();
public virtual ICollection<ProductSpecification> Specifications { get; set; } = new List<ProductSpecification>();
public virtual ICollection<Review> Reviews { get; set; } = new List<Review>();
public virtual ICollection<OrderItem> OrderItems { get; set; } = new List<OrderItem>();
public virtual ICollection<WishlistItem> WishlistItems { get; set; } = new List<WishlistItem>();
[DataType(DataType.DateTime)]
public DateTime CreatedAt { get; set; } = DateTime.Now;
[DataType(DataType.DateTime)]
public DateTime? UpdatedAt { get; set; }
// Computed Properties
[Display(Name = "Average Rating")]
public double AverageRating => Reviews.Any() ? Reviews.Average(r => r.Rating) : 0;
[Display(Name = "Review Count")]
public int ReviewCount => Reviews.Count;
}
}
πΉ ProductImage
C# / ProductImage.cs
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace MobileShop.Models
{
public class ProductImage
{
[Key]
public int Id { get; set; }
[Required]
[StringLength(500)]
[Display(Name = "Image URL")]
public string ImageUrl { get; set; } = string.Empty;
[StringLength(200)]
public string? AltText { get; set; }
[Display(Name = "Display Order")]
public int DisplayOrder { get; set; }
[Display(Name = "Is Main Image")]
public bool IsMainImage { get; set; } = false;
// Foreign Key
[Display(Name = "Product")]
public int ProductId { get; set; }
[ForeignKey("ProductId")]
public virtual Product Product { get; set; } = null!;
}
}
πΉ ProductSpecification
C# / ProductSpecification.cs
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace MobileShop.Models
{
public class ProductSpecification
{
[Key]
public int Id { get; set; }
[Required]
[StringLength(100)]
[Display(Name = "Specification Name")]
public string Name { get; set; } = string.Empty;
[Required]
[StringLength(500)]
[Display(Name = "Specification Value")]
public string Value { get; set; } = string.Empty;
[StringLength(50)]
[Display(Name = "Group Name")]
public string? GroupName { get; set; }
[Display(Name = "Display Order")]
public int DisplayOrder { get; set; }
// Foreign Key
[Display(Name = "Product")]
public int ProductId { get; set; }
[ForeignKey("ProductId")]
public virtual Product Product { get; set; } = null!;
}
}
πΉ Review
C# / Review.cs
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace MobileShop.Models
{
public class Review
{
[Key]
public int Id { get; set; }
[Required]
[Range(1, 5)]
public int Rating { get; set; }
[StringLength(1000)]
public string? Comment { get; set; }
[StringLength(100)]
public string? Title { get; set; }
public bool IsVerifiedPurchase { get; set; } = false;
public bool IsApproved { get; set; } = false;
// Foreign Keys
[Display(Name = "Product")]
public int ProductId { get; set; }
[Display(Name = "User")]
public string UserId { get; set; } = string.Empty;
// Navigation Properties
[ForeignKey("ProductId")]
public virtual Product Product { get; set; } = null!;
[ForeignKey("UserId")]
public virtual ApplicationUser User { get; set; } = null!;
[DataType(DataType.DateTime)]
public DateTime CreatedAt { get; set; } = DateTime.Now;
}
}
πΉ ShoppingCartItem
C# / ShoppingCartItem.cs
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace MobileShop.Models
{
public class ShoppingCartItem
{
[Key]
public int Id { get; set; }
[Required]
public string CartId { get; set; } = string.Empty;
[Required]
public int Quantity { get; set; } = 1;
[DataType(DataType.DateTime)]
public DateTime CreatedAt { get; set; } = DateTime.Now;
// Foreign Key
[Display(Name = "Product")]
public int ProductId { get; set; }
// Navigation Properties
[ForeignKey("ProductId")]
public virtual Product Product { get; set; } = null!;
// Computed Properties
[Column(TypeName = "decimal(18,2)")]
public decimal TotalPrice => Product != null ? Product.SalePrice * Quantity : 0;
}
}
πΉ WishlistItem
C# / WishlistItem.cs
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace MobileShop.Models
{
public class WishlistItem
{
[Key]
public int Id { get; set; }
[DataType(DataType.DateTime)]
public DateTime AddedAt { get; set; } = DateTime.Now;
// Foreign Keys
[Display(Name = "Product")]
public int ProductId { get; set; }
[Display(Name = "User")]
public string UserId { get; set; } = string.Empty;
// Navigation Properties
[ForeignKey("ProductId")]
public virtual Product Product { get; set; } = null!;
[ForeignKey("UserId")]
public virtual ApplicationUser User { get; set; } = null!;
}
}
πΉ Order
C# / Order.cs
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace MobileShop.Models
{
public enum OrderStatus
{
Pending,
Processing,
Shipped,
Delivered,
Cancelled,
Refunded
}
public enum PaymentStatus
{
Pending,
Paid,
Failed,
Refunded
}
public enum PaymentMethod
{
CreditCard,
DebitCard,
PayPal,
Stripe,
CashOnDelivery,
UPI
}
public class Order
{
[Key]
public int Id { get; set; }
[Required]
[StringLength(35)]
[Display(Name = "Order Number")]
public string OrderNumber { get; set; } = GenerateOrderNumber();
[Required]
[Column(TypeName = "decimal(18,2)")]
[Display(Name = "Subtotal")]
public decimal Subtotal { get; set; }
[Column(TypeName = "decimal(18,2)")]
[Display(Name = "Tax Amount")]
public decimal TaxAmount { get; set; }
[Column(TypeName = "decimal(18,2)")]
[Display(Name = "Shipping Cost")]
public decimal ShippingCost { get; set; }
[Column(TypeName = "decimal(18,2)")]
[Display(Name = "Discount Amount")]
public decimal DiscountAmount { get; set; }
[Required]
[Column(TypeName = "decimal(18,2)")]
[Display(Name = "Total Amount")]
public decimal TotalAmount { get; set; }
[Display(Name = "Order Status")]
public OrderStatus Status { get; set; } = OrderStatus.Pending;
[Display(Name = "Payment Status")]
public PaymentStatus PaymentStatus { get; set; } = PaymentStatus.Pending;
[Display(Name = "Payment Method")]
public PaymentMethod PaymentMethod { get; set; }
[StringLength(100)]
[Display(Name = "Transaction ID")]
public string? TransactionId { get; set; }
// Shipping Address
[Required]
[StringLength(200)]
[Display(Name = "Shipping Address")]
public string ShippingAddress { get; set; } = string.Empty;
[Required]
[StringLength(100)]
[Display(Name = "City")]
public string ShippingCity { get; set; } = string.Empty;
[StringLength(20)]
[Display(Name = "Postal Code")]
public string? ShippingPostalCode { get; set; }
[StringLength(50)]
[Display(Name = "Country")]
public string ShippingCountry { get; set; } = "Pakistan";
[StringLength(20)]
[Display(Name = "Phone Number")]
public string? ShippingPhone { get; set; }
[StringLength(500)]
[Display(Name = "Order Notes")]
public string? Notes { get; set; }
[DataType(DataType.DateTime)]
[Display(Name = "Order Date")]
public DateTime OrderDate { get; set; } = DateTime.Now;
[DataType(DataType.DateTime)]
[Display(Name = "Shipped Date")]
public DateTime? ShippedDate { get; set; }
[DataType(DataType.DateTime)]
[Display(Name = "Delivered Date")]
public DateTime? DeliveredDate { get; set; }
// Foreign Key
[Display(Name = "Customer")]
public string? UserId { get; set; }
[ForeignKey("UserId")]
public virtual ApplicationUser? User { get; set; }
// Navigation Properties
public virtual ICollection<OrderItem> OrderItems { get; set; } = new List<OrderItem>();
private static string GenerateOrderNumber()
{
return $"ORD-{DateTime.Now:yyyyMMdd}-{Guid.NewGuid().ToString().Substring(0, 8).ToUpper()}";
}
}
}
πΉ OrderItem
C# / OrderItem.cs
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace MobileShop.Models
{
public class OrderItem
{
[Key]
public int Id { get; set; }
[Required]
public int Quantity { get; set; }
[Required]
[Column(TypeName = "decimal(18,2)")]
[Display(Name = "Unit Price")]
public decimal UnitPrice { get; set; }
[Column(TypeName = "decimal(18,2)")]
[Display(Name = "Discount")]
public decimal Discount { get; set; }
[Required]
[Column(TypeName = "decimal(18,2)")]
[Display(Name = "Total Price")]
public decimal TotalPrice => (UnitPrice * Quantity) - Discount;
// Foreign Keys
[Display(Name = "Order")]
public int OrderId { get; set; }
[Display(Name = "Product")]
public int ProductId { get; set; }
// Navigation Properties
[ForeignKey("OrderId")]
public virtual Order Order { get; set; } = null!;
[ForeignKey("ProductId")]
public virtual Product Product { get; set; } = null!;
}
}
π️ Step 2: Create ApplicationDbContext
Create inside Data folder:
C# / ApplicationDbContext.cs
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using MobileShop.Models;
namespace MobileShop.Data
{
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
public DbSet<Category> Categories { get; set; }
public DbSet<Brand> Brands { get; set; }
public DbSet<Product> Products { get; set; }
public DbSet<ProductImage> ProductImages { get; set; }
public DbSet<ProductSpecification> ProductSpecifications { get; set; }
public DbSet<Review> Reviews { get; set; }
public DbSet<Order> Orders { get; set; }
public DbSet<OrderItem> OrderItems { get; set; }
public DbSet<ShoppingCartItem> ShoppingCartItems { get; set; }
public DbSet<WishlistItem> WishlistItems { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// Configure relationships and constraints
modelBuilder.Entity<Product>(entity =>
{
entity.HasOne(p => p.Category)
.WithMany(c => c.Products)
.HasForeignKey(p => p.CategoryId)
.OnDelete(DeleteBehavior.Restrict);
entity.HasOne(p => p.Brand)
.WithMany(b => b.Products)
.HasForeignKey(p => p.BrandId)
.OnDelete(DeleteBehavior.Restrict);
entity.HasIndex(p => p.Name);
entity.HasIndex(p => p.IsFeatured);
entity.HasIndex(p => p.IsNewArrival);
entity.HasIndex(p => p.IsBestseller);
});
modelBuilder.Entity<Order>(entity =>
{
entity.HasIndex(o => o.OrderNumber).IsUnique();
entity.HasIndex(o => o.Status);
entity.HasIndex(o => o.OrderDate);
});
modelBuilder.Entity<Review>(entity =>
{
entity.HasIndex(r => r.ProductId);
entity.HasIndex(r => r.UserId);
});
modelBuilder.Entity<ShoppingCartItem>(entity =>
{
entity.HasIndex(sci => sci.CartId);
});
// Seed initial data
SeedData(modelBuilder);
}
private void SeedData(ModelBuilder modelBuilder)
{
// Seed Categories
modelBuilder.Entity<Category>().HasData(
new Category { Id = 1, Name = "Smartphones", Description = "Latest smartphones from top brands", DisplayOrder = 1, ImageUrl = "/images/categories/smartphones.jpg" },
new Category { Id = 2, Name = "Feature Phones", Description = "Basic phones with essential features", DisplayOrder = 2, ImageUrl = "/images/categories/feature-phones.jpg" },
new Category { Id = 3, Name = "Accessories", Description = "Phone cases, chargers, and more", DisplayOrder = 3, ImageUrl = "/images/categories/accessories.jpg" },
new Category { Id = 4, Name = "Tablets", Description = "Tablets and iPads", DisplayOrder = 4, ImageUrl = "/images/categories/tablets.jpg" }
);
// Seed Brands
modelBuilder.Entity<Brand>().HasData(
new Brand { Id = 1, Name = "Apple", Description = "Premium smartphones and devices", Country = "USA", WebsiteUrl = "https://www.apple.com" },
new Brand { Id = 2, Name = "Samsung", Description = "Innovative technology solutions", Country = "South Korea", WebsiteUrl = "https://www.samsung.com" },
new Brand { Id = 3, Name = "Xiaomi", Description = "High-quality at affordable prices", Country = "China", WebsiteUrl = "https://www.mi.com" },
new Brand { Id = 4, Name = "OnePlus", Description = "Flagship killer smartphones", Country = "China", WebsiteUrl = "https://www.oneplus.com" },
new Brand { Id = 5, Name = "Google", Description = "Pixel smartphones by Google", Country = "USA", WebsiteUrl = "https://store.google.com" },
new Brand { Id = 6, Name = "Realme", Description = "Dare to leap", Country = "China", WebsiteUrl = "https://www.realme.com" },
new Brand { Id = 7, Name = "Oppo", Description = "Camera phone specialists", Country = "China", WebsiteUrl = "https://www.oppo.com" },
new Brand { Id = 8, Name = "Vivo", Description = "Camera and music phones", Country = "China", WebsiteUrl = "https://www.vivo.com" }
);
}
}
}
⚙️ Step 3: Configure Program.cs
C# / Program.cs
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using MobileShop.Data;
using MobileShop.Models;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
// Database Context
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
// Identity Configuration
builder.Services.AddIdentity<ApplicationUser, IdentityRole>(options =>
{
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Password.RequireUppercase = true;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequiredLength = 6;
options.User.RequireUniqueEmail = true;
options.SignIn.RequireConfirmedEmail = false;
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("AdminOnly", policy => policy.RequireRole("Admin"));
options.AddPolicy("CustomerOnly", policy => policy.RequireRole("Customer"));
});
// Session & Shopping Cart
builder.Services.AddDistributedMemoryCache();
builder.Services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(30);
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
});
// AutoMapper
builder.Services.AddAutoMapper(typeof(Program));
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseSession();
app.UseAuthentication();
app.UseAuthorization();
// Seed Database
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
await DbInitializer.SeedAsync(services);
}
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
π± Step 4: Create DbInitializer (Seeding)
Create file:
C# / DbInitializer.cs
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using MobileShop.Data;
using MobileShop.Models;
namespace MobileShop.Data
{
public static class DbInitializer
{
public static async Task SeedAsync(IServiceProvider serviceProvider)
{
using var scope = serviceProvider.CreateScope();
var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
var userManager = scope.ServiceProvider.GetRequiredService<UserManager<ApplicationUser>>();
var roleManager = scope.ServiceProvider.GetRequiredService<RoleManager<IdentityRole>>();
// Apply pending migrations
await context.Database.MigrateAsync();
// Seed Roles
await SeedRolesAsync(roleManager);
// Seed Admin User
await SeedAdminUserAsync(userManager);
// Seed Sample Products
await SeedProductsAsync(context);
}
private static async Task SeedRolesAsync(RoleManager<IdentityRole> roleManager)
{
string[] roles = { "Admin", "Customer", "Manager" };
foreach (var role in roles)
{
if (!await roleManager.RoleExistsAsync(role))
{
await roleManager.CreateAsync(new IdentityRole(role));
}
}
}
private static async Task SeedAdminUserAsync(UserManager<ApplicationUser> userManager)
{
const string adminEmail = "admin@mobileshop.com";
const string adminPassword = "Admin@123";
var adminUser = await userManager.FindByEmailAsync(adminEmail);
if (adminUser == null)
{
adminUser = new ApplicationUser
{
UserName = adminEmail,
Email = adminEmail,
FirstName = "System",
LastName = "Administrator",
EmailConfirmed = true,
PhoneNumber = "+92-3143076781"
};
var result = await userManager.CreateAsync(adminUser, adminPassword);
if (result.Succeeded)
{
await userManager.AddToRoleAsync(adminUser, "Admin");
}
}
}
private static async Task SeedProductsAsync(ApplicationDbContext context)
{
if (await context.Products.AnyAsync()) return;
var products = new List<Product>
{
new Product
{
Id = 1,
Name = "iPhone 15 Pro Max",
Model = "A2849",
Description = "The most advanced iPhone ever with A17 Pro chip, titanium design, and 48MP camera system.",
ShortDescription = "A17 Pro chip, 48MP camera, titanium design",
OriginalPrice = 159900,
SalePrice = 149900,
StockQuantity = 50,
MainImageUrl = "/images/products/iphone-15-pro-max.jpg",
IsFeatured = true,
IsNewArrival = true,
CategoryId = 1,
BrandId = 1,
Specifications = new List<ProductSpecification>
{
new ProductSpecification { Name = "Display", Value = "6.7\" Super Retina XDR OLED", GroupName = "Display" },
new ProductSpecification { Name = "Processor", Value = "A17 Pro chip", GroupName = "Performance" },
new ProductSpecification { Name = "RAM", Value = "8GB", GroupName = "Performance" },
new ProductSpecification { Name = "Storage", Value = "256GB", GroupName = "Storage" },
new ProductSpecification { Name = "Rear Camera", Value = "48MP Main + 12MP Ultra Wide + 12MP Telephoto", GroupName = "Camera" },
new ProductSpecification { Name = "Front Camera", Value = "12MP TrueDepth", GroupName = "Camera" },
new ProductSpecification { Name = "Battery", Value = "4441 mAh", GroupName = "Battery" },
new ProductSpecification { Name = "OS", Value = "iOS 17", GroupName = "Software" },
new ProductSpecification { Name = "5G", Value = "Yes", GroupName = "Connectivity" },
new ProductSpecification { Name = "Weight", Value = "221g", GroupName = "Physical" }
}
},
new Product
{
Id = 2,
Name = "Samsung Galaxy S24 Ultra",
Model = "SM-S928B",
Description = "Galaxy AI is here. With AI-powered features, 200MP camera, and S Pen functionality.",
ShortDescription = "Galaxy AI, 200MP camera, S Pen included",
OriginalPrice = 129999,
SalePrice = 119999,
StockQuantity = 45,
MainImageUrl = "/images/products/galaxy-s24-ultra.jpg",
IsFeatured = true,
IsBestseller = true,
CategoryId = 1,
BrandId = 2,
Specifications = new List<ProductSpecification>
{
new ProductSpecification { Name = "Display", Value = "6.8\" Dynamic AMOLED 2X", GroupName = "Display" },
new ProductSpecification { Name = "Processor", Value = "Snapdragon 8 Gen 3", GroupName = "Performance" },
new ProductSpecification { Name = "RAM", Value = "12GB", GroupName = "Performance" },
new ProductSpecification { Name = "Storage", Value = "256GB", GroupName = "Storage" },
new ProductSpecification { Name = "Rear Camera", Value = "200MP Main + 50MP Telephoto + 12MP Ultra Wide + 10MP Periscope", GroupName = "Camera" },
new ProductSpecification { Name = "Front Camera", Value = "12MP", GroupName = "Camera" },
new ProductSpecification { Name = "Battery", Value = "5000 mAh", GroupName = "Battery" },
new ProductSpecification { Name = "OS", Value = "Android 14 (One UI 6.1)", GroupName = "Software" },
new ProductSpecification { Name = "5G", Value = "Yes", GroupName = "Connectivity" },
new ProductSpecification { Name = "Weight", Value = "232g", GroupName = "Physical" }
}
},
new Product
{
Id = 3,
Name = "Xiaomi 14 Ultra",
Model = "24031PN0DC",
Description = "Leica optics, Snapdragon 8 Gen 3, and 5300mAh battery with 90W fast charging.",
ShortDescription = "Leica camera, 90W fast charging, flagship performance",
OriginalPrice = 99999,
SalePrice = 89999,
StockQuantity = 30,
MainImageUrl = "/images/products/xiaomi-14-ultra.jpg",
IsFeatured = true,
IsNewArrival = true,
CategoryId = 1,
BrandId = 3,
Specifications = new List<ProductSpecification>
{
new ProductSpecification { Name = "Display", Value = "6.73\" AMOLED 120Hz", GroupName = "Display" },
new ProductSpecification { Name = "Processor", Value = "Snapdragon 8 Gen 3", GroupName = "Performance" },
new ProductSpecification { Name = "RAM", Value = "16GB", GroupName = "Performance" },
new ProductSpecification { Name = "Storage", Value = "512GB", GroupName = "Storage" },
new ProductSpecification { Name = "Rear Camera", Value = "50MP Main + 50MP Telephoto + 50MP Ultra Wide + 50MP Periscope", GroupName = "Camera" },
new ProductSpecification { Name = "Front Camera", Value = "32MP", GroupName = "Camera" },
new ProductSpecification { Name = "Battery", Value = "5300 mAh", GroupName = "Battery" },
new ProductSpecification { Name = "OS", Value = "HyperOS (Android 14)", GroupName = "Software" },
new ProductSpecification { Name = "5G", Value = "Yes", GroupName = "Connectivity" },
new ProductSpecification { Name = "Weight", Value = "219.8g", GroupName = "Physical" }
}
},
new Product
{
Id = 4,
Name = "OnePlus 12",
Model = "CPH2581",
Description = "Smooth beyond belief with 120Hz ProXDR display and Hasselblad camera system.",
ShortDescription = "Hasselblad camera, 100W charging, 120Hz display",
OriginalPrice = 69999,
SalePrice = 64999,
StockQuantity = 40,
MainImageUrl = "/images/products/oneplus-12.jpg",
IsBestseller = true,
CategoryId = 1,
BrandId = 4,
Specifications = new List<ProductSpecification>
{
new ProductSpecification { Name = "Display", Value = "6.82\" LTPO AMOLED 120Hz", GroupName = "Display" },
new ProductSpecification { Name = "Processor", Value = "Snapdragon 8 Gen 3", GroupName = "Performance" },
new ProductSpecification { Name = "RAM", Value = "12GB", GroupName = "Performance" },
new ProductSpecification { Name = "Storage", Value = "256GB", GroupName = "Storage" },
new ProductSpecification { Name = "Rear Camera", Value = "50MP Main + 64MP Telephoto + 48MP Ultra Wide", GroupName = "Camera" },
new ProductSpecification { Name = "Front Camera", Value = "32MP", GroupName = "Camera" },
new ProductSpecification { Name = "Battery", Value = "5400 mAh", GroupName = "Battery" },
new ProductSpecification { Name = "OS", Value = "OxygenOS 14 (Android 14)", GroupName = "Software" },
new ProductSpecification { Name = "5G", Value = "Yes", GroupName = "Connectivity" },
new ProductSpecification { Name = "Weight", Value = "220g", GroupName = "Physical" }
}
},
new Product
{
Id = 5,
Name = "Google Pixel 8 Pro",
Model = "GC3VE",
Description = "The best of Google with AI-powered features and the best camera on a Pixel.",
ShortDescription = "Google AI, best Pixel camera, 7 years updates",
OriginalPrice = 106900,
SalePrice = 99999,
StockQuantity = 25,
MainImageUrl = "/images/products/pixel-8-pro.jpg",
IsNewArrival = true,
CategoryId = 1,
BrandId = 5,
Specifications = new List<ProductSpecification>
{
new ProductSpecification { Name = "Display", Value = "6.7\" LTPO OLED 120Hz", GroupName = "Display" },
new ProductSpecification { Name = "Processor", Value = "Google Tensor G3", GroupName = "Performance" },
new ProductSpecification { Name = "RAM", Value = "12GB", GroupName = "Performance" },
new ProductSpecification { Name = "Storage", Value = "128GB", GroupName = "Storage" },
new ProductSpecification { Name = "Rear Camera", Value = "50MP Main + 48MP Ultra Wide + 48MP Telephoto", GroupName = "Camera" },
new ProductSpecification { Name = "Front Camera", Value = "10.5MP", GroupName = "Camera" },
new ProductSpecification { Name = "Battery", Value = "5050 mAh", GroupName = "Battery" },
new ProductSpecification { Name = "OS", Value = "Android 14", GroupName = "Software" },
new ProductSpecification { Name = "5G", Value = "Yes", GroupName = "Connectivity" },
new ProductSpecification { Name = "Weight", Value = "213g", GroupName = "Physical" }
}
},
new Product
{
Id = 6,
Name = "iPhone 15",
Model = "A3092",
Description = "Dynamic Island, 48MP Main camera, and USB-C. A powerful upgrade.",
ShortDescription = "Dynamic Island, 48MP camera, USB-C",
OriginalPrice = 79900,
SalePrice = 74900,
StockQuantity = 60,
MainImageUrl = "/images/products/iphone-15.jpg",
IsBestseller = true,
CategoryId = 1,
BrandId = 1,
Specifications = new List<ProductSpecification>
{
new ProductSpecification { Name = "Display", Value = "6.1\" Super Retina XDR OLED", GroupName = "Display" },
new ProductSpecification { Name = "Processor", Value = "A16 Bionic", GroupName = "Performance" },
new ProductSpecification { Name = "RAM", Value = "6GB", GroupName = "Performance" },
new ProductSpecification { Name = "Storage", Value = "128GB", GroupName = "Storage" },
new ProductSpecification { Name = "Rear Camera", Value = "48MP Main + 12MP Ultra Wide", GroupName = "Camera" },
new ProductSpecification { Name = "Front Camera", Value = "12MP TrueDepth", GroupName = "Camera" },
new ProductSpecification { Name = "Battery", Value = "3349 mAh", GroupName = "Battery" },
new ProductSpecification { Name = "OS", Value = "iOS 17", GroupName = "Software" },
new ProductSpecification { Name = "5G", Value = "Yes", GroupName = "Connectivity" },
new ProductSpecification { Name = "Weight", Value = "171g", GroupName = "Physical" }
}
},
new Product
{
Id = 7,
Name = "Samsung Galaxy A54 5G",
Model = "SM-A546E",
Description = "Awesome screen, awesome camera, awesome durability at a great price.",
ShortDescription = "120Hz AMOLED, 50MP camera, IP67 waterproof",
OriginalPrice = 38999,
SalePrice = 32999,
StockQuantity = 80,
MainImageUrl = "/images/products/galaxy-a54.jpg",
IsFeatured = true,
CategoryId = 1,
BrandId = 2,
Specifications = new List<ProductSpecification>
{
new ProductSpecification { Name = "Display", Value = "6.4\" Super AMOLED 120Hz", GroupName = "Display" },
new ProductSpecification { Name = "Processor", Value = "Exynos 1380", GroupName = "Performance" },
new ProductSpecification { Name = "RAM", Value = "8GB", GroupName = "Performance" },
new ProductSpecification { Name = "Storage", Value = "128GB", GroupName = "Storage" },
new ProductSpecification { Name = "Rear Camera", Value = "50MP Main + 12MP Ultra Wide + 5MP Macro", GroupName = "Camera" },
new ProductSpecification { Name = "Front Camera", Value = "32MP", GroupName = "Camera" },
new ProductSpecification { Name = "Battery", Value = "5000 mAh", GroupName = "Battery" },
new ProductSpecification { Name = "OS", Value = "Android 14 (One UI 6)", GroupName = "Software" },
new ProductSpecification { Name = "5G", Value = "Yes", GroupName = "Connectivity" },
new ProductSpecification { Name = "Weight", Value = "202g", GroupName = "Physical" }
}
},
new Product
{
Id = 8,
Name = "Realme GT 5 Pro",
Model = "RMX3888",
Description = "Flagship performance with Snapdragon 8 Gen 3 and 5400mAh battery.",
ShortDescription = "Snapdragon 8 Gen 3, 100W charging, periscope camera",
OriginalPrice = 49999,
SalePrice = 44999,
StockQuantity = 35,
MainImageUrl = "/images/products/realme-gt5-pro.jpg",
IsNewArrival = true,
CategoryId = 1,
BrandId = 6,
Specifications = new List<ProductSpecification>
{
new ProductSpecification { Name = "Display", Value = "6.78\" AMOLED 144Hz", GroupName = "Display" },
new ProductSpecification { Name = "Processor", Value = "Snapdragon 8 Gen 3", GroupName = "Performance" },
new ProductSpecification { Name = "RAM", Value = "12GB", GroupName = "Performance" },
new ProductSpecification { Name = "Storage", Value = "256GB", GroupName = "Storage" },
new ProductSpecification { Name = "Rear Camera", Value = "50MP Main + 50MP Periscope + 8MP Ultra Wide", GroupName = "Camera" },
new ProductSpecification { Name = "Front Camera", Value = "32MP", GroupName = "Camera" },
new ProductSpecification { Name = "Battery", Value = "5400 mAh", GroupName = "Battery" },
new ProductSpecification { Name = "OS", Value = "realme UI 5.0 (Android 14)", GroupName = "Software" },
new ProductSpecification { Name = "5G", Value = "Yes", GroupName = "Connectivity" },
new ProductSpecification { Name = "Weight", Value = "218g", GroupName = "Physical" }
}
}
};
await context.Products.AddRangeAsync(products);
await context.SaveChangesAsync();
}
}
}
Configure Connection String
Open : appsettings.json
"ConnectionStrings": {
"DefaultConnection": "Server=.\\SQLEXPRESS;Database=Prc_MobileShop;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True;Encrypt=True"
}
Connection String Explanation
- Server=.\SQLEXPRESS → SQL Server instance
- Database=MobileShop → Database name
- Trusted_Connection=True → Windows authentication
- TrustServerCertificate=True → Avoid SSL certificate issues
What to Seed?
- Admin Role
- Customer Role
- Default Admin User
- Sample Products
𧬠Step 5: Run Migration
add-migration InitialCreate
OR dotnet tool install --global dotnet-ef dotnet ef migrations add InitialCreate
π️ Step 6: Update Database
update-database
ORdotnet ef database update
✅ Database and tables will be created.
π§© Database Structure Overview
Your database now supports:
- Users (Identity)
- Products & Categories
- Orders & Order Items
- Reviews
- Wishlist
- Shopping Cart
π§ Pro Tips
✔ Keep models clean and simple
✔ Use navigation properties properly
✔ Use seeding for default data
✔ Always use migrations properly
π Conclusion
In this part, we successfully built:
- Complete eCommerce Models
- ApplicationDbContext
- Identity Integration
- Database Seeding
- SQL Server Database
π In Part 4, we will build:
- Controllers
- CRUD operations
- Admin panel features

Comments
Post a Comment