{"id":22065759,"url":"https://github.com/karenpayneoregon/learn-bogus-efcore","last_synced_at":"2026-05-09T14:42:50.291Z","repository":{"id":110840609,"uuid":"525971017","full_name":"karenpayneoregon/learn-bogus-efcore","owner":"karenpayneoregon","description":"Learn Bogus with C# and EF Core 7","archived":false,"fork":false,"pushed_at":"2023-01-21T15:19:06.000Z","size":183,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-29T00:29:25.921Z","etag":null,"topics":["bogus","csharp-core","ef-core"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/karenpayneoregon.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-08-17T22:19:40.000Z","updated_at":"2024-07-06T05:51:13.000Z","dependencies_parsed_at":null,"dependency_job_id":"d4318dfe-3d04-4e00-ad17-d303f68425e9","html_url":"https://github.com/karenpayneoregon/learn-bogus-efcore","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karenpayneoregon%2Flearn-bogus-efcore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karenpayneoregon%2Flearn-bogus-efcore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karenpayneoregon%2Flearn-bogus-efcore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karenpayneoregon%2Flearn-bogus-efcore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/karenpayneoregon","download_url":"https://codeload.github.com/karenpayneoregon/learn-bogus-efcore/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245144978,"owners_count":20568056,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bogus","csharp-core","ef-core"],"created_at":"2024-11-30T19:21:48.050Z","updated_at":"2026-05-09T14:42:50.276Z","avatar_url":"https://github.com/karenpayneoregon.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Using EF Core and Bogus\n\nIn this article with basic to intermediate code sample, learn how to generate data which can be used for working through data schemas along with Entity Framework Core ([EF Core](https://learn.microsoft.com/en-us/ef/core/)) using [Bogus](https://github.com/bchavez/Bogus).\n\nWhat is Bogus? \n\n*A simple fake data generator for C#, F#, and VB.NET. Based on and ported from the famed faker.js.*\n\n\u003e **Note**\n\u003e Code presented was originally written in VS2019, .NET Core 5 and has been updated to .NET Core 7, EF Core 7 using VS2022.\n\nThe first step when working with databases is to plan out the schema which comes from business requirements. Once the schema is in place write SQL statements to validate all operations can be performed or some will want this done bypassing [SQL statement](https://learn.microsoft.com/en-us/sql/t-sql/statements/statements?view=sql-server-ver16) and use their EF Core code. The other path is to test with SQL and EF Core.\n\nSome will want to do this with a mocking framework like [Progress Telerik JustMock](https://www.telerik.com/products/mocking.aspx) and EF Core [in-memory](https://learn.microsoft.com/en-us/ef/core/providers/in-memory/?tabs=dotnet-core-cli) testing which doesn�t fully replicate working with databases.\n\nThis is where Bogus NuGet package [![](assets/Link_16x.png)](https://www.nuget.org/packages/Bogus) comes into play. Bogus provides everything needed to create mocked data for your database. Check out their documentation and code samples to get an idea how to work with Bogus. There can be a problem with novice developers/coders in how to put everything together which is where this article will assist novice developers/coders.\n\n\n## Step 1\n\nOnce the database has been created, [scaffold/reverse engineer](https://learn.microsoft.com/en-us/ef/core/managing-schemas/scaffolding/?tabs=dotnet-core-cli) to create a DbContext and models\n\n## Step 2\n\nWrite code to create the database and tables, the following code is used in each project.\n\nEach place will have a different `DbContext`, in this case `NorthWindContext`.\n\n```csharp\n// create or recreate database\nawait using var context = new NorthWindContext();\nawait context.Database.EnsureDeletedAsync();\nawait context.Database.EnsureCreatedAsync();\n```\n\nOnce done start writing code to create fake data, here there are two models, `Categories` and `Products`.\n\n```csharp\npublic partial class Categories\n{\n    public Categories()\n    {\n        Products = new HashSet\u003cProducts\u003e();\n    }\n\n    public int CategoryId { get; set; }\n    public string CategoryName { get; set; }\n\n    public virtual ICollection\u003cProducts\u003e Products { get; set; }\n}\n```\n\n\u003c/br\u003e\n\n```csharp\n    public partial class Products\n    {\n        public int ProductId { get; set; }\n        public string ProductName { get; set; }\n        public int? CategoryId { get; set; }\n        public decimal? UnitPrice { get; set; }\n        public short? UnitsInStock { get; set; }\n\n        public virtual Categories Category { get; set; }\n    }\n```\n\n\u003c/br\u003e\n\n**Important notes**\n\n- Going forward, the secret to knowing were to find data is to read [Bogus](https://github.com/bchavez/Bogus) information in the readme file which goes into depth were to find paths to generate data. This is very important as you can clash with their classes e.g. you create a Person class and guess what, Bogus has a Person class. This is were knowing how to work with `using` statements and `using` statements with `aliasing`.\n- We don't create primary keys, EF Core does this for us.\n\n\n## Step 3\n\nCode to generate a single category using [Bogus](https://github.com/bchavez/Bogus) where `f.Commerce.Categories(1)` selects one category name from an array, `[0]` indicates we want the first category name.\n\nNote there is a parameter which specifies how many records to create which defaults to 4.\n\nThe last line `return fake.Generate(count);` performs generating and returns the generated list to the caller which is next up.\n\n```csharp\npublic static List\u003cCategories\u003e CategoriesList(int count = 4)\n{\n    var fake = new Faker\u003cCategories\u003e()\n        .RuleFor(c =\u003e c.CategoryName, f =\u003e f.Commerce.Categories(1)[0]);\n\n    return fake.Generate(count);\n}\n```\n\n\u003c/br\u003e\n\nThe following code uses `CategoriesList` to generate the Product list\n\n\n```csharp\npublic static List\u003cProducts\u003e ProductsList(int productCount, int categoryCount)\n{\n    Faker\u003cProducts\u003e fake = new Faker\u003cProducts\u003e()\n        .RuleFor(p =\u003e p.ProductName, f =\u003e f.Address.County())\n        .RuleFor(p =\u003e p.UnitPrice, f =\u003e f.Random.Decimal(10,45))\n        .RuleFor(p =\u003e p.UnitsInStock, f =\u003e f.Random.Short(1,5))\n        .RuleFor(p =\u003e p.CategoryId, f =\u003e f.Random.Int(1,categoryCount));\n\n    return fake.Generate(productCount);\n}\n\npublic static async Task\u003c(bool success, Exception exception)\u003e CreateDatabaseAndPopulate(int productCount) \n{\n    try\n    {\n        await using var context = new NorthWindContext();\n        await context.Database.EnsureDeletedAsync();\n        await context.Database.EnsureCreatedAsync();\n\n        List\u003cCategories\u003e categories = CategoriesList();\n        await context.AddRangeAsync(categories);\n\n        List\u003cProducts\u003e products = ProductsList(productCount, categories.Count);\n        await context.AddRangeAsync(products);\n        await context.SaveChangesAsync();\n\n        return (true, null);\n    }\n    catch (Exception localException)\n    {\n        return (false, localException);\n    }\n}\n```\n\n## Calling above code\n\nWe call the code to generate data in the following method.\n\n1. Ask permission to continue, this is important if you ran the process and don't want to regenerate.\n2. Method is called to generate the data\n\n\n```csharp\nprivate static async Task Initialize(int count)\n{\n    AnsiConsole.MarkupLine(\"[skyblue1]Creating and populating database[/]\");\n            \n    var (success, exception) = await BogusOperations.CreateDatabaseAndPopulate(count);\n\n    if (!success)\n    {\n        AnsiConsole.Clear();\n        AnsiConsole.MarkupLine(\"[red]Failed to create and populated[/]\");\n        Console.WriteLine(exception.Message);\n    }\n}\n```\n\n## Reading data\n\nAfter the code to generate executes and returns without any errors the following code shows the generated data.\n\n```csharp\nprivate static async Task ReadProducts()\n{\n    AnsiConsole.Clear();\n\n    List\u003cProducts\u003e list = await DataOperations.GetProductsList();\n\n    var table = new Table()\n        .RoundedBorder()\n        .AddColumn(\"[b]Id[/]\")\n        .AddColumn(\"[b]Name[/]\")\n        .AddColumn(\"[b]Unit price[/]\")\n        .AddColumn(\"[b]Category[/]\")\n        .Alignment(Justify.Center)\n        .BorderColor(Color.LightSlateGrey)\n        .Title(\"[LightGreen]Products[/]\");\n\n\n    foreach (var product in list)\n    {\n        // ReSharper disable once PossibleInvalidOperationException\n        table.AddRow(product.ProductId.ToString(), product.ProductName, product.UnitPrice.Value.ToString(\"C2\"), product.Category.CategoryName);\n    }\n\n    AnsiConsole.Write(table);\n            \n    Console.WriteLine();\n    AnsiConsole.MarkupLine(\"Press [b]any[/] key to leave\");\n\n    Console.ReadLine();\n\n}\n```\n\n## Protecting generated data\n\nOnce data has been generated suppose you don't want to overwrite it? The following statement can tell us all tables are populated.\n\n```sql\nSELECT   T.name AS TableName, SI.rows AS NumberOfRows\nFROM     sys.tables AS T INNER JOIN sys.sysindexes AS SI ON T.object_id = SI.id\nWHERE    (SI.indid IN (0, 1)) AND T.name \u003c\u003e 'sysdiagrams'\nORDER BY NumberOfRows DESC, TableName\n```\n\n**Basics to run in code**\n\nPlace the query into a method as shown below\n\n```csharp\npublic class SqlStatements\n{\n    public static string AllTablesHaveRecords =\u003e \"SELECT T.name TableName,i.Rows NumberOfRows FROM sys.tables T JOIN sys.sysindexes I ON T.OBJECT_ID = I.ID WHERE indid IN (0,1) ORDER BY i.Rows DESC,T.name\";\n}\n```\n\n:pushpin:  Create a method to check if all tables are populated\n\n```csharp\npublic static bool TablesArePopulated()\n{\n    using var cn = new SqlConnection(ConfigurationHelper.ConnectionString());\n    using var cmd = new SqlCommand(SqlStatements.AllTablesHaveRecords, cn);\n\n    DataTable table = new();\n    cn.Open();\n\n    table.Load(cmd.ExecuteReader());\n    return table.AsEnumerable()\n        .All(row =\u003e row.Field\u003cint\u003e(\"NumberOfRows\") \u003e 0);\n\n}\n```\n\nTo check if the datbase exists (code is in several projects), create a new instance of a DbContext and call it `await someContext.CanConnectAsync();`\n\n```csharp\npublic static class EntityFrameworkExtensions\n{\n    public static async Task\u003c(bool success, Exception exception)\u003e CanConnectAsync(this DbContext context)\n    {\n        try\n        {\n            var result = await Task.Run(async () =\u003e await context.Database.CanConnectAsync());\n            return (result, null);\n        }\n        catch (Exception e)\n        {\n            return (false, e);\n        }\n    }\n}\n```\n\n## See also\n\n- [Learn DateOnly \u0026 TimeOnly](https://dev.to/karenpayneoregon/learn-dateonly-timeonly-23j0) which works with Bogu\n\n\n## Summary\n\nThis article provides code samples to fake/generate data with one example HasDataConsoleApp which generates data directly in the DbContext for a single table while the remaining projects show how to work with one to many models.\n\nTake time to run each console project, study the code than read the readme file at the Bogus GitHub repository [![](assets/Link_16x.png)](https://github.com/bchavez/Bogus) and note at the end of the readme page there are other free packages to enhance Bogus.\n\n:small_blue_diamond: I can not stress enough to read the documentation on [Bogus](https://github.com/bchavez/Bogus) rather than just work with provided code. See [featured in](https://github.com/bchavez/Bogus#featured-in) also.\n\n## See also\n\n:pushpin:  [FluentValidation tips C#](https://dev.to/karenpayneoregon/fluentvalidation-tips-c-3olf)\n\n\n## Requires\n\n- Microsoft Visual Studio 2022 or higher\n- .NET Core 7 or higher\n- SQL-Server Express installed\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkarenpayneoregon%2Flearn-bogus-efcore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkarenpayneoregon%2Flearn-bogus-efcore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkarenpayneoregon%2Flearn-bogus-efcore/lists"}