LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

【C#】使用 NewId 庫在 .NET 中生成可排序的唯一ID

admin
2024年4月9日 22:21 本文熱度 781

摘要

在本文中,我們將探討為什么我們?cè)?.NET 中可能需要可排序的唯一ID,以及如何使用 NewId NuGet 包來創(chuàng)建它們。

原文 Generate Sortable Unique IDs With the NewId Library in .NET 由 Ivan Gechev 撰寫。


在本文中,我們將探討為什么我們?cè)?.NET 中可能需要可排序的唯一ID,以及如何使用 NewId NuGet 包來創(chuàng)建它們。

要下載本文的源代碼,您可以訪問我們的 GitHub 倉庫

為什么我們?cè)?.NET 中需要可排序的唯一ID

我們都知道,生成項(xiàng)目中實(shí)體的ID有兩種主要方法:要么是 int,要么是 Guid(全局唯一標(biāo)識(shí)符)值。但這兩種方法都有它們的問題。讓我們?cè)谝粋€(gè)處理客戶訂單的 API 中探討一下。

整數(shù)作為主鍵

首先,讓我們看看整數(shù)作為主鍵:

public class Order
{
    public int Id { get; set; }
    public required string CustomerName { get; set; }
    public required IEnumerable<string> Products { get; set; }
    public required decimal TotalAmount { get; set; }
}

我們創(chuàng)建了一個(gè) Order 類并使用 int 作為ID。

采用這種方法,我們將ID生成工作交給數(shù)據(jù)庫提供商。好處是我們得到了短小、美觀、連續(xù)的ID。但,使用數(shù)據(jù)庫生成的主鍵,我們遇到一個(gè)主要缺點(diǎn) —— 我們的應(yīng)用程序變得更難擴(kuò)展。處理大量的插入語句迫使我們的數(shù)據(jù)庫不斷使用鎖來處理生成新的主鍵。

在幾個(gè)不同的數(shù)據(jù)庫中存儲(chǔ)實(shí)體并維護(hù)唯一的 int ID也幾乎是不可能的。另外,我們可能會(huì)向我們的競爭對(duì)手泄露敏感信息 - 我們是否希望擁有連續(xù)的ID并讓別人確切知道我們有多少訂單?

全局唯一標(biāo)識(shí)符作為主鍵

另一種流行的方法是使用 Guid 值:

public class OrderService(IUnitOfWork unitOfWork) : IOrderService
{
    public async Task<OrderDto> CreateAsync(
        OrderForCreationDto orderForCreationDto,
        CancellationToken cancellationToken = default
)

    {
        var order = new Order
        {
            Id = Guid.NewGuid(),
            CustomerName = orderForCreationDto.CustomerName,
            Products = orderForCreationDto.Products,
            TotalAmount = orderForCreationDto.TotalAmount,
        };
        unitOfWork.OrderRepository.Insert(order);
        await unitOfWork.SaveChangesAsync(cancellationToken);
        return new OrderDto
        {
            Id = order.Id,
            CustomerName = order.CustomerName,
            Products = order.Products,
            TotalAmount = order.TotalAmount,
        };
    }
    // 省略以簡潔
}

我們首先將 Order 的標(biāo)識(shí)從 int 變更為 Guid,然后我們創(chuàng)建了 OrderService 類。我們的項(xiàng)目基于 Onion 架構(gòu),所以我們的服務(wù)使用一個(gè) Dto 對(duì)象,處理它,并使用倉庫將實(shí)體插入數(shù)據(jù)庫。

采用這種方法,OrderService 類負(fù)責(zé)生成主鍵值。最大的好處在于我們可以使用 Guid.NewGuid() 輕松獲得唯一ID。擁有唯一但隨機(jī)的ID使我們的應(yīng)用擴(kuò)展到幾個(gè)數(shù)據(jù)庫變得非常容易。但這也是它們最大的問題:它使我們的數(shù)據(jù)基于主鍵單獨(dú)排序變得不可能,并可能導(dǎo)致潛在的索引問題。這種類型的主鍵在數(shù)據(jù)庫中存儲(chǔ)時(shí)也會(huì)占用四倍于常規(guī)整數(shù)的空間。

這就是 NewId 庫發(fā)揮作用的地方。通過使用它,我們結(jié)合了 int 和 Guid 主鍵的優(yōu)點(diǎn),同時(shí)消除了一些缺點(diǎn)。

NewId 庫是什么

NewId 庫是一個(gè) NuGet 包,我們可以用它來生成唯一但可排序的ID。 它基于現(xiàn)已退役的 Snowflake:X(前 Twitter)內(nèi)部服務(wù),用于生成可排序的唯一主鍵。NewId 是分布式應(yīng)用框架 MassTransit 的一部分,旨在解決 int 和 Guid 標(biāo)識(shí)符存在的問題。其目的是提供一種在大規(guī)模下生成唯一且可排序ID的方法。

該包基于三個(gè)事物生成ID - 時(shí)間戳、工作ID和進(jìn)程ID。這樣我們最終得到的是雖然唯一但仍可排序的ID,并且當(dāng)我們的應(yīng)用和數(shù)據(jù)庫有多個(gè)實(shí)例時(shí)不會(huì)發(fā)生沖突。

這個(gè)材料對(duì)你有用嗎?考慮訂閱并免費(fèi)獲取 ASP.NET Core Web API 最佳實(shí)踐 電子書!

在我們開始生成ID之前,我們需要安裝 NewId 包:

dotnet add package NewId

使用 dotnet add package 命令,我們安裝了這個(gè)庫。

現(xiàn)在我們已經(jīng)準(zhǔn)備好了,讓我們開始使用這個(gè)包來生成ID。

要生成我們的可排序唯一ID,我們需要使用 NewId 類。它位于 MassTransit 命名空間中,有三個(gè)方法。

首先是 Next() 方法 - 生成一個(gè)新的 NewId 類實(shí)例:

00070000-ac11-0242-3d9b-08dc45bed613
00070000-ac11-0242-c9d3-08dc45bed614
00070000-ac11-0242-cafd-08dc45bed614
00070000-ac11-0242-cb2e-08dc45bed614
00070000-ac11-0242-cb69-08dc45bed614

接下來,NextGuid() 方法 - 生成一個(gè)新的 Guid 值:

00070000-ac11-0242-df20-08dc45bed614
00070000-ac11-0242-0c11-08dc45bed615
00070000-ac11-0242-0d30-08dc45bed615
00070000-ac11-0242-0d46-08dc45bed615
00070000-ac11-0242-0d58-08dc45bed615

最后,NextSequentialGuid() 方法 - 生成一個(gè)新的順序 Guid 值:

08dc45be-d615-19b5-0242-ac1100070000
08dc45be-d615-1b01-0242-ac1100070000
08dc45be-d615-1b46-0242-ac1100070000
08dc45be-d615-1b66-0242-ac1100070000
08dc45be-d615-1ba4-0242-ac1100070000

我們可以看到,使用 Next() 和 NextGuid() 方法,我們得到相同的模式,其中 NextSequentialGuid() 方法有稍微不同的模式。后兩種方法返回一個(gè) Guid 值,我們的類不需要修改,但如果我們選擇 Next() 方法,我們將需要更改我們 Order 類的ID類型。

讓我們使用其中一個(gè):

public class OrderService(IUnitOfWork unitOfWork) : IOrderService
{
    public async Task<OrderDto> CreateAsync(
        OrderForCreationDto orderForCreationDto,
        CancellationToken cancellationToken = default
)

    {
        var order = new Order
        {
            Id = NewId.NextSequentialGuid(),
            CustomerName = orderForCreationDto.CustomerName,
            Products = orderForCreationDto.Products,
            TotalAmount = orderForCreationDto.TotalAmount,
        };
        unitOfWork.OrderRepository.Insert(order);
        await unitOfWork.SaveChangesAsync(cancellationToken);
        return new OrderDto
        {
            Id = order.Id,
            CustomerName = order.CustomerName,
            Products = order.Products,
            TotalAmount = order.TotalAmount,
        };
    }
    // 省略以簡潔
}

在我們的 OrderService 類中,我們生成ID的地方,我們用 NewId.NextSequentialGuid() 方法替換了 Guid.NewGuid() 方法。這是我們唯一需要做的改變。

讓我們運(yùn)行我們的 API 并添加一些訂單:

[
  {
    "id": "08dc45c0-b5b5-0d5d-5811-22b038790000",
    "customerName": "Marcel Waters",
    "products": ["Piano"],
    "totalAmount": 599.99
  },
  {
    "id": "08dc45c0-d6f4-fbed-5811-22b038790000",
    "customerName": "Elizabeth Doyle",
    "products": ["Vase", "Mirror", "Blanket"],
    "totalAmount": 49.39
  },
  {
    "id": "08dc45c0-f143-a9f9-5811-22b038790000",
    "customerName": "Rayford Lopez",
    "products": ["Headphones", "Microphone"],
    "totalAmount": 86.06
  }
]

我們可以看到,我們的實(shí)體現(xiàn)在擁有唯一但不完全隨機(jī)的標(biāo)識(shí)符,這些標(biāo)識(shí)符可以排序。

何時(shí)不應(yīng)使用 NewId 庫生成可排序的唯一ID

雖然 NewId 庫為我們提供了生成可排序唯一ID的便利,但在一些場景下我們應(yīng)該避免使用它們。至關(guān)重要的是要記住,我們生成的ID具有一定程度的可預(yù)測性。當(dāng)你知道它們的創(chuàng)建算法時(shí),它們可以被猜測。

因此,當(dāng)不可預(yù)測性和安全性至關(guān)重要時(shí),最好不要使用 NewId 生成的ID。我們不應(yīng)該在需要高度保密性的敏感信息如密碼、安全令牌或任何其他數(shù)據(jù)上使用這樣的ID。如果我們?cè)谶@樣的場景下依賴 NewId 庫,我們可能會(huì)危及我們應(yīng)用程序的安全。這可能會(huì)使它們暴露于漏洞和未經(jīng)授權(quán)的訪問中。因此,當(dāng)我們的應(yīng)用程序在安全上有重要需求時(shí),需要格外小心。

結(jié)論

在本文中,我們探討了在作為主鍵時(shí),整數(shù)和全局唯一標(biāo)識(shí)符的限制,以及需要一種新方法的原因。NewId NuGet 包為我們提供了一個(gè)解決方案,提供了基于時(shí)間戳、工作ID和進(jìn)程ID組合的唯一、可排序的ID。通過使用 NewId 庫,我們獲得了 int 和 Guid 主鍵的好處,同時(shí)減少了它們的缺點(diǎn)。這使我們能夠輕松實(shí)現(xiàn)可擴(kuò)展性、有效的索引,并提高我們的數(shù)據(jù)組織。所有這些最終增強(qiáng)了我們的應(yīng)用程序的健壯性和功能。


該文章在 2024/4/9 22:21:59 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場、車隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲(chǔ)管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

黄频国产免费高清视频,久久不卡精品中文字幕一区,激情五月天AV电影在线观看,欧美国产韩国日本一区二区
亚洲Aⅴ男人的天堂在线观看 | 制服丝袜中文字幕自拍有码 | 日本韩国偷拍视频对白不卡高清精品 | 亚洲综合偷拍欧美一区 | 亚洲中文字幕乱码久久 | 日韩亚洲欧美一区二区三区在线 |