EF Core áá²á· Database-First áá»ááºážáááºááŸá¯ááŸá¬ á¡áááá¡áá»áá¯á¶áž command ááá±á¬á· ááŸáááŒá®ážáá¬áž Database Schema ááᯠC# code ááœá±á¡ááŒá
Ạgenerate áá¯ááºáá±ážáá²á· dotnet ef dbcontext scaffold ááŒá
áºáá«áááºá Database ááá¯ááºááá¯ááºááᯠáááºáá±á¬ááºááŒááºáž (CREATE DATABASE) ááá±á¬á· áá»á¬ážáá±á¬á¡á¬ážááŒáá·áº SQL Server Management Studio (SSMS) ááᯠtool áá»áá¯ážáá²á· áá®ážááá·áºáá¯ááºáá±á¬ááºááá±á·ááŸááá«áááºá
áá®á¡ááá·áºááá±á¬á· CLI áá²á·ááá¯ááºááá¯ááºááááºááá¯ááºáá² ááŒáá¯áááºáá¯ááºáá±á¬ááºáá¬ážáááá·áº áá áºáá¯áááºážáá±á¬ á¡ááá¯ááºážááŒá áºáá«áááºá SQL Server Management Studio (SSMS) ááá¯á·ááá¯áẠááŸá áºáááºáᬠSQL tool ááá¯áá¯á¶ážááŒá®áž Database áá²á· Table ááᯠá¡áááºáááºáá±á¬ááºáá¬ážááá¯á· ááá¯á¡ááºáá«áááºá
-- 1. Database ááᯠá¡áááºáá±á¬ááºáá«áááºá
CREATE DATABASE MiniPOS;
GO
-- 2. áá±á¬ááºáá¬ážáá²á· Database ááᯠáá¯á¶ážááŒá®áž Table áá±á¬ááºáá«áááºá
USE MiniPOS;
GO
CREATE TABLE [dbo].[Tbl_Product]( [ProductId] [int] IDENTITY(1,1) NOT NULL, [ProductCode] [varchar](50) NOT NULL, [ProductName] [nvarchar](100) NOT NULL, [Price] [decimal](18, 2) NOT NULL, [DeleteFlag] [bit] NOT NULL CONSTRAINT [DF_Tbl_Product_DeleteFlag] DEFAULT ((0)), CONSTRAINT [PK_Tbl_Product] PRIMARY KEY CLUSTERED ([ProductId] ASC)
);
GOá¡áᯠVisual Studio ááá¯á¡áá¯á¶ážááŒá¯ááŒá®áž áá»áœááºáá±á¬áºááá¯á·áá²á· Solution áá²á· Project ááœá±ááᯠáá±á¬ááºáá«áááºá
- Create a Blank Solution
- Visual Studio ááá¯ááœáá·áºááŒá®áž Create a new project ááá¯ááŸáááºáá«á
- Search bar ááŸá¬ Blank Solution ááá¯á·ááá¯ááºááŸá¬ááŒá®áž Next ááá¯ááŸáááºáá«á
- Solution name ááá¯
MiniPOSááá¯á·áá±ážááŒá®áž ááááºážáááºážááá·áºáá±áᬠ(Location) ááá¯ááœá±ážáᬠCreate ááá¯ááŸáááºáá«á
- Add the Database Class Library Project
- Solution Explorer ááŸá¬ áá»áœááºáá±á¬áºááá¯á·áá²á· Solution (
Solution 'MiniPOS') áá±á«áºááŸá¬ Right-click ááŸáááºááŒá®áž Add > New Project... ááá¯ááœá±ážáá«á - Search bar ááŸá¬ Class Library ááá¯á·ááá¯ááºááŸá¬ááŒá®áž C# template ááá¯ááœá±ážáᬠNext ááŸáááºáá«á
- Project name ááá¯
MiniPOS.Databaseááá¯á·áá±ážááŒá®áž Next ááŸáááºáá«á - Framework ááᯠ(.NET 8.0 or your preferred version) ááœá±ážááŒá®áž Create ááá¯ááŸáááºáá«á
- Solution Explorer ááŸá¬ áá»áœááºáá±á¬áºááá¯á·áá²á· Solution (
- Add the Web API Project
- Solution Explorer ááŸá¬ áá»áœááºáá±á¬áºááá¯á·áá²á· Solution áá±á«áºááŸá¬áá² Right-click ááŸáááºááŒá®áž Add > New Project... ááá¯ááœá±ážáá«á
- Search bar ááŸá¬ ASP.NET Core Web API ááá¯á·ááá¯ááºááŸá¬ááŒá®áž C# template ááá¯ááœá±ážáᬠNext ááŸáááºáá«á
- Project name ááá¯
MiniPOS.WebAPIááá¯á·áá±ážááŒá®áž Next ááŸáááºáá«á - Framework ááá¯ááœá±ážááŒá®áž áá»ááºáá²á· settings ááœá±ááᯠdefault á¡ááá¯ááºážáá¬ážáᬠCreate ááá¯ááŸáááºáá«á
áá«ááá¯ááẠáá»áœááºáá±á¬áºááá¯á·áá²á· Solution ááŸá¬ Project ááŸá áºáá¯áá²á· á¡ááŒá±áá¶ Structure á¡áááºááá·áºááŒá áºááœá¬ážáá«ááŒá®á
áá®á¡ááá·áºááŸá¬áá±á¬á· áá»áœááºáá±á¬áºááá¯á·áá²á· MiniPOS.Database Project áá²ááᯠá¡ááá·áº á ááŸá¬ áá±á¬ááºáá²á·áá²á· Database ááá± EF Core Models ááœá±áá²á· DbContext ááᯠgenerate áá¯ááºáá«áááºá
-
Install Required Packages
MiniPOS.Database project áá²ááᯠááá¯á¡ááºáá²á· EF Core NuGet package ááœá±ááᯠinstall áá¯ááºáá«áááºá
dotnet add package Microsoft.EntityFrameworkCoredotnet add package Microsoft.EntityFrameworkCore.Designdotnet add package Microsoft.EntityFrameworkCore.SqlServerdotnet add package Microsoft.EntityFrameworkCore.ToolsInstall áá¯ááºááá¯á· ááŒá®ážáá¬áá²á· Build á¡áááºáá¯ááºáá« ááá¯ááºáá² Scaffold Run ááá¯ááºáááº
Microsoft.EntityFrameworkCore.DesignPackage áááŸááá°ážááá¯áá²á· Error ááᯠááŒá±ááŸááºážáá»ááºááá¯á·áá« -
Run the Scaffold
MiniPOS.Databaseproject ááŸá¬ Right-click ááŸáááºááŒá®áž Open in Terminal ááá¯ááŸáááºáá«á dotnet ef dbcontext scaffold command ááᯠrun áá«áááºá áá«áᬠDatabase-First áá²á· á¡ááá command ááŒá áºáá«áááºádotnet ef dbcontext scaffold "Server=.;Database=MiniPOS;User ID=sa;Password=sasa@123;TrustServerCertificate=True;" Microsoft.EntityFrameworkCore.SqlServer -o AppDbContextModels -c AppDbContext -f
áá® command ááᯠrun ááá¯ááºáá¬áá²á·
MiniPOS.Databaseproject áá²ááŸá¬DataFolder á¡áá áºáá áºáá¯áAppDbContext.csáá²á·TblProduct.csfile ááœá±ááᯠá¡ááá¯á¡áá»á±á¬áẠgenerate áá¯ááºáá±ážááœá¬ážááŸá¬ ááŒá áºáá«áááºá
á¡áᯠáá»áœááºáá±á¬áºááá¯á·áá²á· MiniPOS.WebAPI Project ááá± MiniPOS.Database Project ááᯠááŸááºážá¡áá¯á¶ážááŒá¯ááá¯ááºááá¯á·á¡ááœáẠproject reference ááá·áºáá±ážááá¯á· ááá¯á¡ááºáá«áááºá
- Solution Explorer ááŸá¬
MiniPOS.WebAPIproject á¡á±á¬ááºá Dependencies áá±á«áºááŸá¬ Right-click ááŸáááºááŒá®áž Add Project Reference... ááá¯ááœá±ážáá«á - áá±á«áºáá¬áá²á· window ááŸá¬
MiniPOS.Databaseááᯠá¡ááŸááºááŒá áºáá±ážááŒá®áž OK ááá¯ááŸáááºáá«á
áá»áœááºáá±á¬áºááá¯á·áá²á· API Project áá
áºáá¯áá¯á¶ážááŸá¬ AppDbContext ááᯠá¡ááœááºááá° áá±á«áºáá¯á¶ážááá¯ááºá¡á±á¬áẠ(Dependency Injection) Program.cs file ááŸá¬ service á¡áá±áá²á· register áá¯ááºáá±ážááá«áááºá
-
Add Connection String in appsettings.json
áá»áœááºáá±á¬áºááá¯á·áá²á· MiniPOS.WebAPI Project áá²á appsettings.json file ááŸá¬ Database Connection String ááᯠá¡áá¯ááá¯ááá·áºáá±ážáá«áááºá
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*", "ConnectionStrings": { "DbConnection": "Server=.;Database=MiniPOS;User ID=sa;Password=sasa@123;TrustServerCertificate=True;" } } -
Register DbContext Service in Program.cs
MiniPOS.WebAPIProject áá²á·Program.csfile ááá¯ááœáá·áºááŒá®ážbuilder.Services.AddControllers();ááá¯áá²á· line áá²á·á¡áá±á«áºááŸá¬ á¡á±á¬ááºá code ááœá±ááᯠáááºááá·áºáá±ážáá«áááºá// ... other using statements using Microsoft.EntityFrameworkCore; using MiniPOS.Database.Data; // áá»áœááºáá±á¬áºááá¯á·áá²á· DbContext ááŸááá²á·áá±áá¬ááᯠusing ááá·áºáá±ážááá¯á· ááá¯á¡ááºáá«ááẠvar builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddDbContext<AppDbContext>(options => { options.UseSqlServer(builder.Configuration.GetConnectionString("DbConnection")); }, ServiceLifetime.Transient, ServiceLifetime.Transient); builder.Services.AddControllers(); // ... rest of the file
Note
MiniPOS.WebAPIproject ááŸá¬Microsoft.EntityFrameworkCore.SqlServerpackage ááᯠááá·áºáá±ážááá¯á· ááá¯á¡ááºáá«áááºáManage NuGet Packages...ááá± install áá¯ááºááá¯ááºáá«áááºá
á¡á¬ážáá¯á¶ážááŒááºáááºááŒá®ážááŒá®ááá¯áá±á¬á· áá»áœááºáá±á¬áºááá¯á·áá²á· API Controller ááᯠEF Core áá¯á¶ážááŒá®áž áá±á¬ááºáá«áááºá áá® Controller á AppDbContext ááᯠinject áá¯ááºááŒá®áž Database operations (CRUD) ááœá±ááᯠáá¯ááºáá±á¬ááºááŸá¬ááŒá
áºáá«áááºá
MiniPOS.WebAPI/Controllers Folder ááŸá¬ ProductController.cs ááá¯áá²á· file á¡áá
áºáá
áºáᯠáá±á¬ááºááŒá®áž á¡á±á¬ááºá code ááœá±ááᯠáá±ážááŒáá«áááºá Code line ááá¯ááºážá¡ááœáẠáá¬áá¯ááºáááºááá¯áá¬ááᯠcomment ááŸá¬ ááŸááºážááŒáá¬ážáá«áááºá
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using MiniPOS.Database.Data; // áá»áœááºáá±á¬áºááá¯á·áá²á· DbContext áá²á· Model ááœá±ááŸááá²á· namespace
using System.Linq;
using System.Threading.Tasks;
namespace MiniPOS.WebAPI.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ProductController : ControllerBase
{
private readonly AppDbContext _context;
// Program.cs ááŸá¬ register áá¯ááºáá¬ážáá²á· AppDbContext ááᯠConstructor ááá± inject áá¯ááºááŒá®áž áá°áá¯á¶ážáá«áááºá
public ProductController(AppDbContext context)
{
_context = context;
}
[HttpGet]
public async Task<IActionResult> GetProducts()
{
// EF Core ááá± Data á¡á¬ážáá¯á¶ážááᯠToListAsync() áá²á· ááœá²áá¯ááºááŒá®áž return ááŒááºáá±ážáá«áááºá
var lst = await _context.TblProducts.Where(x => x.DeleteFlag == false).ToListAsync();
return Ok(lst);
}
[HttpGet("{id}")]
public async Task<IActionResult> GetProductById(int id)
{
// FirstOrDefaultAsync() method áá²á· ID ááá¯ááºáá®áá²á· Data áá
áºááŒá±á¬ááºážááá¯áá² ááŸá¬áá«áááºá
var item = await _context.TblProducts.FirstOrDefaultAsync(x => x.ProductId == id && x.DeleteFlag == false);
if (item is null)
{
return NotFound("No Data Found.");
}
return Ok(item);
}
[HttpPost]
public async Task<IActionResult> CreateProduct(TblProduct product)
{
// Request ááá±áá«áá¬áá²á· Product object ááᯠDbContext áá²ááá¯ááá·áºáá«áááºá
await _context.TblProducts.AddAsync(product);
// SaveChangesAsync() á Database ááŸá¬ á¡ááŸááºáááẠááááºážáááºážáá±ážáá²á· command ááŒá
áºáá«áááºá
var result = await _context.SaveChangesAsync();
return Ok(result > 0 ? "Saving Successful." : "Saving Failed.");
}
[HttpPatch("{id}")]
public async Task<IActionResult> UpdateProduct(int id, TblProduct product)
{
// á¡áááºáá¯á¶áž ááŒááºáá»ááºáá²á· Data ááŸááááŸá ID áá²á· ááŸá¬áá«áááºá
var item = await _context.TblProducts.FirstOrDefaultAsync(x => x.ProductId == id && x.DeleteFlag == false);
if (item is null)
{
return NotFound("No Data Found.");
}
// ááŸááááºááá¯ááẠRequest ááŸá¬áá«áá¬áá²á· Data á¡áá
áºááœá±áá²á· á¡á
á¬ážááá¯ážáá«áááºá
item.ProductCode = product.ProductCode;
item.ProductName = product.ProductName;
item.Price = product.Price;
// Database ááŸá¬ ááŒááºááááºážáá«áááºá
var result = await _context.SaveChangesAsync();
return Ok(result > 0 ? "Updating Successful." : "Updating Failed.");
}
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteProduct(int id)
{
// áá»ááºáá»ááºáá²á· Data ááᯠID áá²á· ááŸá¬áá«áááºá
var item = await _context.TblProducts.FirstOrDefaultAsync(x => x.ProductId == id && x.DeleteFlag == false);
if (item is null)
{
return NotFound("No Data Found.");
}
// Data ááᯠá¡ááŸááºááááºááá»ááºáá² DeleteFlag ááá¯áá² true ááŒá±á¬ááºážáá«ááẠ(Soft Delete)
item.DeleteFlag = true;
// Database ááŸá¬ ááŒááºááááºážáá«áááºá
var result = await _context.SaveChangesAsync();
return Ok(result > 0 ? "Deleting Successful." : "Deleting Failed.");
}
}
}áá®á¡ááá·áºááááá¯áááºáá±á¬á· áá»áœááºáá±á¬áºááá¯á·áá²á· EF Core Database-First application ááᯠDatabase áááºáá±á¬ááºáá¬ááá±á ááŒá®áž API á¡áá¯ááºáá¯ááºáá²á·á¡áá á¡á±á¬ááºááŒááºá áœá¬ áááºáá±á¬ááºááŒá®ážááŒá áºáá«áááºá áá®ááá¯á áá áºááá» Layer ááœá²ááŒá®ážáááºáá±á¬ááºáá¬ážáá¬ááŒá±á¬áá·áº áá±á¬ááºááá¯ááºážááœá±ááŸá¬ ááŒá¯ááŒááºááááºážááááºážááᬠá¡ááœááºááœááºáá°ááŸá¬ ááŒá áºáá«áááºá