1. 程式人生 > >.NET使用Bogus生成大量隨機資料

.NET使用Bogus生成大量隨機資料

.NET如何生成大量隨機資料

在演示Demo、資料庫脫敏、效能測試中,有時需要生成大量隨機資料。Bogus就是.NET中優秀的高效能、合理、支援多語言的隨機資料生成庫。

BogusGithub連結:https://github.com/bchavez/Bogus,圖示如下:

安裝Bogus

目前Bogus最新版是28.0.2,本文演示基本該版本,不保證官方以後會不會修改本文的使用方式。

使用Powershell

PM> Install-Package Bogus -Version 28.0.2

或者使用PackageReference

<PackageReference Include="Bogus" Version="28.0.2" />

使用

我的資料生成程式碼如下(程式碼使用LINQPad執行,可以幾乎複製到Visual Studio中執行,效果一樣,其中.Dump()LINQPad特有方法):

void Main()
{
    var userGenerator = new Faker<User>()
        .RuleFor(x => x.Id, x => x.IndexFaker + 1)
        .RuleFor(x => x.Gender, x => x.Person.Gender)
        .RuleFor(x => x.FirstName, (x, u) => x.Name.FirstName(u.Gender))
        .RuleFor(x => x.LastName, (x, u) => x.Name.LastName(u.Gender))
        .RuleFor(x => x.Email, (x, u) => x.Internet.Email(u.FirstName, u.LastName))
        .RuleFor(x => x.BirthDate, x => x.Person.DateOfBirth)
        .RuleFor(x => x.Company, x => x.Person.Company.Name)
        .RuleFor(x => x.Phone, x => x.Person.Phone)
        .RuleFor(x => x.Website, x => x.Person.Website)
        .RuleFor(x => x.SSN, x => x.Person.Ssn());
        
    userGenerator.GenerateForever().Take(10).Dump();
}

class User
{
    public int Id { get; set; }
    public Bogus.DataSets.Name.Gender Gender { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public DateTime BirthDate { get; set; }
    public string Company { get; set; }
    public string Phone { get; set; }
    public string Website { get; set; }
    public string SSN { get; set; }
}

生成的資料如圖所示:

注意細節,姓名FirstName/LastName是會根據性別Gender來隨機生成的,然後郵箱Email欄位也會根據FirstName/LastName來相應地生成,並非完全隨機,毫無規律。這些規則是通過.RuleFor()第二個回撥的第二個欄位來決定的:

.RuleFor(x => x.FirstName, (x, u) => x.Name.FirstName(u.Gender)) // 根據Gender生成FirstName
.RuleFor(x => x.LastName, (x, u) => x.Name.LastName(u.Gender))   // 根據Gender生成LastName
.RuleFor(x => x.Email, (x, u) => x.Internet.Email(u.FirstName, u.LastName)) // 根據姓名生成郵箱

最後的.GenerateForever返回了一個IEnumerable<User>,是一個狀態機,可以永久生成資料。

Bogus也提供了一次性生成快取資料的方法:List<User> Generate(int count)。但由於我可能將這些資料做今後部落格文章的效能測試原始資料,資料量可能會非常大,如果將這些資料快取起來將非常浪費記憶體,並且影響效能。因此本例中我使用GenerateForever來生成原始資料。

通過.NET Core 3.0最新提供的System.Text.Json裡面的JsonSerializerUtf8JsonWriter,我可能以極其高效的方法將這些測試資料序列化為JSON,然後儲存到磁碟中:

string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"\test-data.json";
using var file = File.Create(path);
using var writer = new Utf8JsonWriter(file, new JsonWriterOptions { Indented = true });
var data = userGenerator.GenerateForever().Take(6_0000);
JsonSerializer.Serialize(writer, data);
Process.Start("explorer", @$"/select, ""{path}""".Dump()); // 資源管理器開啟test-data.json資料夾

演示和下載

最後示例資料如下:

一共6萬條資料,每條資料有10個欄位,test-data.json19,166 KB

可以用如下程式碼將這6萬條資料載入到.NET記憶體:

void Main()
{
    string path = @"C:\Users\sdfly\Desktop\test-data\test-data.json";
    byte[] bytes = File.ReadAllBytes(path);
    var users = JsonSerializer.Deserialize<List<User>>(bytes);
    // 資料分析演示
    users.GroupBy(x => x.Email[x.Email.IndexOf('@')..])
        .Select(x => new { Host = x.Key, Count = x.Count() })
        .Dump();
}

class User
{
    public int Id { get; set; }
    public int Gender { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public DateTime BirthDate { get; set; }
    public string Company { get; set; }
    public string Phone { get; set; }
    public string Website { get; set; }
    public string SSN { get; set; }
}

結果如下:

所有郵件都是hotmail.com/gmail.com/yahoo.com三種郵箱的均勻分佈,每種大約都在20000左右。

我計劃今後如需要做效能測試或者演示,將使用該檔案作為基準資料,已經上傳到Github,該檔案可以從https://github.com/sdcb/blog-data/tree/master/2019/20190821-generate-lorem-data下載。

出處:微信公眾號【DotNet騷操作】
原文連結:https://www.cnblogs.com/sdflysha/p/20190821-generate-lorem-data.h