0Pricing
C# Academy · บทเรียน

การดำเนินการ CRUD ด้วย EF Core

ดำเนินการสร้าง อ่าน อัปเดต และลบข้อมูลด้วยการติดตามการเปลี่ยนแปลงของ EF Core และ SaveChanges

การดำเนินการ CRUD ด้วย EF Core เป็นบทเรียน C# Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C# Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน

ภาพรวมการดำเนินการ CRUD ใน EF Core

EF Core รองรับการดำเนินการ CRUD ทั้งสี่แบบ ได้แก่ สร้าง อ่าน อัปเดต และลบ ผ่านการทำงานร่วมกันของการติดตามการเปลี่ยนแปลงและ SaveChangesAsync() การทำความเข้าใจตัวติดตามการเปลี่ยนแปลงคือกุญแจสำคัญในการใช้งาน CRUD ได้อย่างเชี่ยวชาญ

สร้าง: การเพิ่มเอนทิตีใหม่

ใช้ DbSet.Add() หรือ AddAsync() เพื่อทำเครื่องหมายเอนทิตีว่าเป็น เพิ่มแล้ว เมื่อเรียกใช้ SaveChangesAsync() EF Core จะสร้างคำสั่ง INSERT และเติมค่าคีย์ที่เพิ่มขึ้นโดยอัตโนมัติ

var order = new Order
{
    CustomerId = 5,
    PlacedAt   = DateTime.UtcNow,
    Status     = OrderStatus.Pending
};

await _db.Orders.AddAsync(order);
await _db.SaveChangesAsync();

Console.WriteLine(order.Id); // populated by DB

การเพิ่มกราฟของเอนทิตี

การเพิ่มเอนทิตีแม่พร้อมเอนทิตีลูกในการเรียกใช้ครั้งเดียวจะแทรกกราฟออบเจ็กต์ทั้งหมด EF Core จะจัดการความสัมพันธ์ของ FK โดยอัตโนมัติ

var order = new Order
{
    CustomerId = 5,
    PlacedAt   = DateTime.UtcNow,
    Lines      = new List<OrderLine>
    {
        new() { ProductId = 10, Quantity = 2, Price = 49.99m },
        new() { ProductId = 11, Quantity = 1, Price = 19.99m }
    }
};

_db.Orders.Add(order);
await _db.SaveChangesAsync();
// Inserts Order + 2 OrderLines in one transaction

อ่าน: การสอบถามด้วย LINQ

EF Core จะแปลงนิพจน์ LINQ เป็น SQL คุณสามารถประกอบการสอบถามโดยใช้ Where, Select, OrderBy เป็นต้น แล้วแปลงผลลัพธ์เป็นข้อมูลจริงด้วย ToListAsync หรือ FirstOrDefaultAsync

// Read all pending orders for a customer
var orders = await _db.Orders
    .Where(o => o.CustomerId == 5 && o.Status == OrderStatus.Pending)
    .OrderByDescending(o => o.PlacedAt)
    .Select(o => new OrderSummaryDto
    {
        Id     = o.Id,
        Total  = o.Lines.Sum(l => l.Quantity * l.Price),
        Status = o.Status.ToString()
    })
    .ToListAsync();

อ่าน: การค้นหาเอนทิตีเดียว

สำหรับการอ่านเอนทิตีเดียว ให้ใช้ FindAsync (ตรวจสอบตัวติดตามก่อน) หรือ FirstOrDefaultAsync / SingleOrDefaultAsync พร้อมเงื่อนไขกรอง

// By PK (checks cache first)
var order = await _db.Orders.FindAsync(orderId);

// By predicate (always hits DB)
var latest = await _db.Orders
    .Where(o => o.CustomerId == 5)
    .OrderByDescending(o => o.PlacedAt)
    .FirstOrDefaultAsync();

อัปเดต: การติดตามการเปลี่ยนแปลง

เอนทิตีที่โหลดผ่าน EF Core จะได้รับการติดตาม แก้ไขพร็อพเพอร์ตีได้โดยตรง แล้วเรียกใช้ SaveChangesAsync() EF Core จะตรวจพบความแตกต่างและสร้างคำสั่ง UPDATE ที่มีเฉพาะการเปลี่ยนแปลงที่จำเป็น

var order = await _db.Orders.FindAsync(orderId);
if (order is null) return;

order.Status   = OrderStatus.Shipped;
order.ShippedAt = DateTime.UtcNow;

await _db.SaveChangesAsync();
// UPDATE Orders SET Status=..., ShippedAt=... WHERE Id=orderId

อัปเดต: การอัปเดตจำนวนมาก (EF Core 7+)

ExecuteUpdateAsync จะอัปเดตแถวในฐานข้อมูลโดยตรงโดยไม่ต้องโหลดเอนทิตี จึงมีประสิทธิภาพสูงกว่ามากสำหรับการดำเนินการจำนวนมาก

// Mark all overdue orders as Cancelled — no loading needed
await _db.Orders
    .Where(o => o.Status == OrderStatus.Pending
             && o.PlacedAt < DateTime.UtcNow.AddDays(-30))
    .ExecuteUpdateAsync(set => set
        .SetProperty(o => o.Status, OrderStatus.Cancelled)
        .SetProperty(o => o.UpdatedAt, DateTime.UtcNow));

ลบ: การลบเอนทิตีเดียว

เรียกใช้ Remove() กับเอนทิตีที่กำลังถูกติดตาม แล้วเรียกใช้ SaveChangesAsync() หากคุณมีเพียง ID ให้ค้นหาเอนทิตีก่อน หรือใช้ ExecuteDeleteAsync

var order = await _db.Orders.FindAsync(orderId);
if (order is null) return;

_db.Orders.Remove(order);
await _db.SaveChangesAsync();
// DELETE FROM Orders WHERE Id=orderId

ลบ: การลบจำนวนมาก (EF Core 7+)

ExecuteDeleteAsync จะส่งคำสั่ง DELETE ของ SQL เพียงคำสั่งเดียวโดยไม่ต้องโหลดเอนทิตี จึงเหมาะอย่างยิ่งสำหรับการล้างข้อมูลเป็นชุด

// Delete all cancelled orders older than 1 year
int deleted = await _db.Orders
    .Where(o => o.Status == OrderStatus.Cancelled
             && o.PlacedAt < DateTime.UtcNow.AddYears(-1))
    .ExecuteDeleteAsync();

Console.WriteLine($"Deleted {deleted} old orders");

ธุรกรรม

การดำเนินการทั้งหมดภายในการเรียกใช้ SaveChangesAsync ครั้งเดียวจะถูกห่อหุ้มไว้ในธุรกรรม สำหรับการดำเนินการหลายขั้นตอนที่ครอบคลุมการบันทึกหลายครั้ง ให้ใช้ธุรกรรมที่กำหนดไว้อย่างชัดเจน

using var transaction = await _db.Database.BeginTransactionAsync();
try
{
    _db.Orders.Add(newOrder);
    await _db.SaveChangesAsync();

    inventory.Stock -= newOrder.Quantity;
    await _db.SaveChangesAsync();

    await transaction.CommitAsync();
}
catch
{
    await transaction.RollbackAsync();
    throw;
}

กรณีใช้งานจริง: บริการ CRUD แบบครบถ้วน

บริการที่สมบูรณ์จะห่อหุ้มการดำเนินการ CRUD ทั้งหมด พร้อมจัดการข้อผิดพลาดอย่างเหมาะสม และส่งคืนออบเจ็กต์ถ่ายโอนข้อมูล (DTO) เพื่อไม่เปิดเผยรายละเอียดภายในของเอนทิตี

public async Task<OrderDto> CreateOrderAsync(CreateOrderRequest req)
{
    var order = new Order { CustomerId = req.CustomerId, PlacedAt = DateTime.UtcNow };
    _db.Orders.Add(order);
    await _db.SaveChangesAsync();
    return new OrderDto { Id = order.Id, Status = order.Status.ToString() };
}

public async Task<bool> CancelOrderAsync(int id)
{
    int rows = await _db.Orders
        .Where(o => o.Id == id && o.Status == OrderStatus.Pending)
        .ExecuteUpdateAsync(s =>
            s.SetProperty(o => o.Status, OrderStatus.Cancelled));
    return rows > 0;
}

ตรวจสอบความเข้าใจ

ข้อดีของ ExecuteUpdateAsync / ExecuteDeleteAsync เหนือการโหลดเอนทิตีแล้วเรียกใช้ SaveChangesAsync คืออะไร

ทบทวน: การดำเนินการ CRUD ด้วย EF Core

ประเด็นสำคัญ:

  • Add + SaveChangesAsync → INSERT โดย EF Core จะเติมค่าคีย์ที่สร้างขึ้นโดยอัตโนมัติ
  • แก้ไขเอนทิตีที่กำลังถูกติดตาม + SaveChangesAsync → UPDATE เฉพาะส่วนที่เปลี่ยนแปลง
  • Remove + SaveChangesAsync → DELETE สำหรับเอนทิตีเดียว
  • ExecuteUpdateAsync / ExecuteDeleteAsync → การดำเนินการจำนวนมากโดยไม่ต้องโหลดเอนทิตี (EF Core 7+)
  • ห่อหุ้มการดำเนินการหลายขั้นตอนไว้ในธุรกรรมที่กำหนดไว้อย่างชัดเจนเพื่อให้การดำเนินการเป็นอะตอมิก

คำถามที่พบบ่อย

บทเรียน “การดำเนินการ CRUD ด้วย EF Core” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การดำเนินการ CRUD ด้วย EF Core” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C# Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การดำเนินการ CRUD ด้วย EF Core”

ดำเนินการสร้าง อ่าน อัปเดต และลบข้อมูลด้วยการติดตามการเปลี่ยนแปลงของ EF Core และ SaveChanges คุณปฏิบัติ C# Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C# Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน C# Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “การดำเนินการ CRUD ด้วย EF Core” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน C# Academy นี้ได้ไหม

ได้ บทเรียน C# Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. พื้นฐาน DbContext และ DbSet
  2. การย้ายข้อมูลและการจัดการสคีมา
  3. การดำเนินการ CRUD ด้วย EF Core
  4. ความสัมพันธ์: หนึ่งต่อหลายและหลายต่อหลาย
← กลับไปที่ C# Academy