chatGPT幫助開發實戰解答問題和反思

 

問題來自.Net開發羣友

 

問題

我想做一個自動生成單據號的功能,但是在EFCORE裏沒有行級鎖,請有什麼等價方案嗎?

 

ChatGPT回答

在 EF Core 中確實沒有提供行級鎖(row-level locking)的功能,因爲這需要對數據庫進行顯式的鎖定操作,而 EF Core 的設計理念是儘可能不與數據庫直接交互,而是通過抽象層面的數據操作來實現,因此不鼓勵使用顯式的鎖定操作。

不過,在 EF Core 中提供了樂觀併發控制(Optimistic Concurrency Control)的功能,可以用於處理類似於行級鎖的需求。樂觀併發控制基於版本號(Version)機制實現,每個實體對象都有一個版本號屬性,當兩個用戶同時更新同一個實體對象時,EF Core 會比較它們的版本號,如果版本號不一致,則表示有衝突發生,需要執行相應的衝突解決邏輯。

因此,如果你想實現自動生成單據號的功能,並保證其唯一性,可以考慮使用樂觀併發控制的方案。具體的實現思路如下:

  1. 在你的實體對象中增加一個版本號屬性,類型爲整數。

  2. 在生成單據號前,使用 EF Core 查詢最後一條記錄的單據號和版本號,得到最新的單據號和版本號。

  3. 在生成單據號時,將版本號加 1,並將單據號和版本號寫入到新的記錄中。如果寫入數據庫時發生衝突,則表示有其他用戶同時在生成單據號,此時可以重新獲取最新的單據號和版本號,並再次嘗試生成。

以下是一個簡單的示例代碼,演示瞭如何使用樂觀併發控制來生成唯一的單據號

public class Order
{
    public int Id { get; set; }
    public string OrderNo { get; set; }
    public int Version { get; set; }
}

public class OrderContext : DbContext
{
    public DbSet<Order> Orders { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Order>()
            .Property(o => o.Version)
            .IsConcurrencyToken();
    }
}

public class OrderService
{
    private readonly OrderContext _context;

    public OrderService(OrderContext context)
    {
        _context = context;
    }

    public string GenerateOrderNo()
    {
        string lastOrderNo = _context.Orders
            .OrderByDescending(o => o.Id)
            .Select(o => o.OrderNo)
            .FirstOrDefault();

        int lastVersion = _context.Orders
            .OrderByDescending(o => o.Id)
            .Select(o => o.Version)
            .FirstOrDefault();

        string newOrderNo = GenerateNewOrderNo(lastOrderNo);

        var order = new Order
        {
            OrderNo = newOrderNo,
            Version = lastVersion + 1
        };

        _context.Orders.Add(order);

        try
        {
            _context.SaveChanges();
        }
        catch (DbUpdateConcurrencyException ex)
        {
            // 處理併發衝突
            ex.Entries.Single().Reload();
            lastOrderNo = _context.Orders
                .OrderByDescending(o => o.Id)
                .Select(o=> o.OrderNo) .FirstOrDefault(); lastVersion = _context.Orders .OrderByDescending(o => o.Id) .Select(o => o.Version) .FirstOrDefault(); newOrderNo = GenerateNewOrderNo(lastOrderNo); order.OrderNo = newOrderNo; order.Version = lastVersion + 1; _context.SaveChanges(); } return newOrderNo; } private string GenerateNewOrderNo(string lastOrderNo) { // 生成新的單據號邏輯 // ... }
}

 

反思

EFCORE 和 行級鎖,如果提問者不知道這兩者的含義根本沒法問,就算問了,回答的東西,所以chatGPT對提問者也是有要求的

再沒有chatGPT以前,我們碼農如果遇到這個問題如何解決了?

很簡單,使用各種搜索引擎,或者詢問同行,蒐集零碎的信息然後最終拼湊起來

程序員在有了chatGPT之後,有什麼變化?

顯而易見,縮短了搜索的時間

總結

其實不管是以前的面向搜索引擎編程,還是面向羣友編程,其實都在暗中隱喻了程序員的未來——架構師

開發軟件應用,最終是爲了人類某個行業提供多一種可選方式

(例如外賣,古代也有外賣,讓店小二提餐走路送去大戶人家家裏

  後來有了馬車,單車,直到現在的摩托車,什麼變了?方式變了,最終目的並沒有改變

做開發其實也是一個道理,我們並不是做一個XX軟件去替代,而是爲了原本的最終目的提供多一種方式,而程序員則是這多出來的一種方式的設計師,讓這個新的方式更加的容易被大衆接納和方便使用

要不然,我原本方式很簡單,爲什麼要用你給我提供的方式呢?近些年開發行業也經常出現這種本末倒置的情況,很多碼農都不知道自己開發這些軟件應用的目的到底是爲什麼,對於我們開發者而言

不管什麼技術,只是爲了達成最終目的的手段,而不是最終目的

 

這也是我實在不喜歡背誦一些照本宣科的書面理論知識,而是更熱衷提出和發現程序的到設計思路

說了這麼多隻是想說,程序員的未來肯定會是架構師,我們所有的技術積累我個人看來只是爲了讓我們的思維從普通人轉換成程序員思維,而且我相信在未來,編程思維會如同喫飯一樣,成爲每個人的必備

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章