{"id":22065728,"url":"https://github.com/karenpayneoregon/master-ef-core","last_synced_at":"2026-04-29T14:33:14.079Z","repository":{"id":110840639,"uuid":"484458582","full_name":"karenpayneoregon/master-ef-core","owner":"karenpayneoregon","description":"Teaching EF Core","archived":false,"fork":false,"pushed_at":"2022-08-19T16:21:12.000Z","size":564,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-29T00:29:17.234Z","etag":null,"topics":["bogus","csharp-core","efcore","entity-framework-core","extension-methods","fluentvalidation","sql-server","unit-testing"],"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-04-22T14:13:05.000Z","updated_at":"2024-06-11T18:40:53.000Z","dependencies_parsed_at":null,"dependency_job_id":"659d6133-3f15-4ebd-9fea-cdcca9b04491","html_url":"https://github.com/karenpayneoregon/master-ef-core","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%2Fmaster-ef-core","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karenpayneoregon%2Fmaster-ef-core/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karenpayneoregon%2Fmaster-ef-core/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karenpayneoregon%2Fmaster-ef-core/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/karenpayneoregon","download_url":"https://codeload.github.com/karenpayneoregon/master-ef-core/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","efcore","entity-framework-core","extension-methods","fluentvalidation","sql-server","unit-testing"],"created_at":"2024-11-30T19:21:39.577Z","updated_at":"2026-04-29T14:33:14.009Z","avatar_url":"https://github.com/karenpayneoregon.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Efcore Csharp](assets/efcore_csharp.png)\n\nThis repository is for getting started with Entity Framework Core[^1] basics and some intermediate and advance topics.\n\nWhen working with EF Core, there are several avenues to start.\n\n- Writing code to configure a database, tables and relationships. Once code is written a developer uses migrations[^2] to create and optionally populate the database.\n- Reverse Engineering[^3] a database which is the process of scaffolding entity type classes and a DbContext class based on a database schema.\n\n## Loading data\n\n- [Eager](https://docs.microsoft.com/en-us/ef/core/querying/related-data/eager) loading means that the related data is loaded from the database as part of the initial query.\n  - Entity Framework Core will automatically fix-up navigation properties to any other entities that were previously loaded into the context instance. So even if you don't explicitly include the data for a navigation property, the property may still be populated if some or all of the related entities were previously loaded.\n- [Explicit](https://docs.microsoft.com/en-us/ef/core/querying/related-data/explicit) loading means that the related data is explicitly loaded from the database at a later time.\n- [Lazy](https://docs.microsoft.com/en-us/ef/core/querying/related-data/lazy) loading means that the related data is transparently loaded from the database when the navigation property is accessed.\n  - Friends don't let friends use lazy loading\n\nIn the code samples within this repository `eager` loading is used.\n\n\n# Local NuGet feeds\n\n\n# Sample query statements\n\nThe following is the model for queries to follow.\n\nTwo missing, Customers and Categories.\n\n![Order Order Details](assets/OrderOrderDetails.png)\n\n**Get first details for specific order**\n\nHere only the order and the first detail is read back. Note `Include` performs egar loading of the order.\n\n```csharp\nint orderId = 10248;\nusing var context = new NorthwindContext();\n\nOrderDetails details = context.OrderDetails\n    .Include(ord =\u003e ord.Order)\n    .FirstOrDefault(ord =\u003e ord.OrderId == orderId);\n```\n\n**Get first detail, `employee`, `customer` and `Shipping`**\n\n```csharp\nOrders order = context.Orders\n    .Include(ord =\u003e ord.Employee)\n    .Include(ord =\u003e ord.CustomerIdentifierNavigation)\n    .Include(ord =\u003e ord.ShipViaNavigation)\n    .FirstOrDefault(ord =\u003e ord.OrderId == orderId);\n```\n\n**List of all order details with different joins**\n\n```csharp\nList\u003cOrderDetails\u003e details = context.OrderDetails\n    .Include(ordd =\u003e ordd.Product)\n    .Include(ordd =\u003e ordd.Product.Category)\n    .Include(ordd =\u003e ordd.Product.Supplier)\n    .Where(ord =\u003e ord.OrderId == order.OrderId).ToList();\n```\n\n\n```csharp\npublic static async Task\u003cOrders\u003e GetOrder(int orderId = 10248)\n{\n    await using var context = new NorthwindContext();\n\n    return await context\n        .Orders\n        .Include(ord =\u003e ord.OrderDetails)\n        .ThenInclude(ord =\u003e ord.Product)\n        .Where(ord =\u003e ord.OrderId == orderId)\n        .FirstOrDefaultAsync();\n}\n```\n\nResults,several tables are not included.\n\n![imag](assets/figure1.png)\n\n\nAnything can be included or excluded as needed and what makes sense.\n\n# Entity Framework Core shadow properties\n\n[Shadow properties](https://docs.microsoft.com/en-us/ef/core/modeling/shadow-properties) are properties that are not defined in your .NET entity class but are defined for that entity type in the EF Core model. The value and state of these properties is maintained purely in the Change Tracker. Shadow properties are useful when there is data in the database that should not be exposed on the mapped entity types. Code samples presented will provided simple, useful examples for using shadow properties using a class project for Entity Framework Core code logic with a Windows form project to present data from a SQL-Server database\n\n# Query tags\n\n[Query tags](https://docs.microsoft.com/en-us/ef/core/querying/tags) help correlate LINQ queries in code with generated SQL queries captured in logs.  Information in `TagWith` are available in SQL-Server profiler, unsure about Oracle tools.\n\n![demo](assets/tagWith.png)\n\n# Tracking Queries\n\n[Tracking](https://docs.microsoft.com/en-us/ef/core/querying/tracking) behavior controls if Entity Framework Core will keep information about an entity instance in its change tracker. If an entity is tracked, any changes detected in the entity will be persisted to the database during SaveChanges(). EF Core will also fix up navigation properties between the entities in a tracking query result and the entities that are in the change tracker.\n\nFor example, if `Contacts` are used for display only [AsNoTracking](https://docs.microsoft.com/en-us/dotnet/api/system.data.entity.dbextensions.asnotracking?view=entity-framework-5.0.0) would be used which means any changes are not tracked.\n\n```csharp\npublic static async Task\u003cList\u003cContacts\u003e\u003e ByType(List\u003cint\u003e identifiers)\n{\n    return await Task.Run(async () =\u003e\n    {\n        await using var context = new NorthwindContext();\n        return await context.Contacts.AsNoTracking()\n            .Where(currentContact =\u003e\n                currentContact.ContactTypeIdentifier.HasValue \u0026\u0026\n                identifiers.Contains(currentContact.ContactTypeIdentifier ?? 0))\n            .ToListAsync();\n\n    });\n}\n```\n\n\u003c/br\u003e\n\n\u003e Now in most cases no tracking will be used as there usually is a disconnect between a read and save operation in which case mark the changed entity state and save back to a new DbContext.\n\nExample for examining current and original values\n\n```csharp\npublic static List\u003cChangeContainer\u003e ShowEventsChangesPlain()\n{\n\n    List\u003cChangeContainer\u003e changedList = new();\n\n    /*\n     * Note that Person is alias for Person1 done in the DbContext\n     */\n    foreach (Person currentPerson in Context.Person.Local)\n    {\n        if (Context.Entry(currentPerson).State != EntityState.Unchanged)\n        {\n            ChangeContainer item = new ()\n            {\n\n                Id = currentPerson.Id,\n\n                CurrentFirstName = currentPerson.FirstName,\n                OriginalFirstName = Context.Entry(currentPerson).Property(person =\u003e person.FirstName).OriginalValue,\n\n                CurrentLastName = currentPerson.LastName,\n                OriginalLastName = Context.Entry(currentPerson).Property(person =\u003e person.LastName).OriginalValue,\n\n                CurrentBirthDate = currentPerson.BirthDate,\n                OriginalBirthDate = Context.Entry(currentPerson).Property(person =\u003e person.BirthDate).OriginalValue,\n\n                EntityState = Context.Entry(currentPerson).State\n            };\n\n            changedList.Add(item);\n        }\n    }\n\n    return changedList;\n\n}\n```\n\nAnother option is to use ChangeTracker.DebugView.[LongView](https://docs.microsoft.com/en-us/ef/core/change-tracking/debug-views#the-long-view) or ChangeTracker.DebugView.[ShortView](https://docs.microsoft.com/en-us/ef/core/change-tracking/debug-views#the-short-view)\n\nThe nice thing with a little thinking is to wrap LongView into a language extensions to control what is returned when there are many entities being tracked.\n\nKaren's extensions\n\n```csharp\n/// \u003csummary\u003e\n/// Extension methods for assisting in both learning EF Core and debugging.\n/// \u003c/summary\u003e\n/// \u003cremarks\u003e\n/// See also  https://docs.microsoft.com/en-us/ef/core/change-tracking/debug-views\n/// Note that future releases of EF Core may break these methods but should be easy to tweak.\n/// \u003c/remarks\u003e\npublic static class DebugViewExtensions\n{\n    /// \u003csummary\u003e\n    /// Filter LongView\n    /// \u003c/summary\u003e\n    /// \u003cparam name=\"sender\"\u003e\u003c/param\u003e\n    /// \u003cparam name=\"tokens\"\u003eFilter token array\u003c/param\u003e\n    /// \u003cparam name=\"chunkSize\"\u003e\u003c/param\u003e\n    /// \u003creturns\u003efiltered view\u003c/returns\u003e\n    public static string CustomViewByChunks(this DebugView sender, string[] tokens, int chunkSize)\n    {\n        var longViewLinesList = sender\n            .LongView.Split(new[] { Environment.NewLine }, StringSplitOptions.None)\n            .ToList();\n\n        /*\n         * Split LongView into chunks\n         */\n        var chunks = longViewLinesList.ChunkBy(chunkSize);\n\n        StringBuilder builder = new();\n\n        /*\n         * Incrementally find items in tokens array\n         */\n        foreach (var chunk in chunks)\n        {\n            foreach (var item in chunk)\n            {\n                if (item.Has(tokens))\n                {\n                    builder.AppendLine(item);\n                }\n            }\n        }\n\n        return builder.ToString();\n\n    }\n\n    /// \u003csummary\u003e\n    /// Variation of the above\n    /// \u003c/summary\u003e\n    /// \u003cparam name=\"sender\"\u003e\u003c/param\u003e\n    /// \u003cparam name=\"tokens\"\u003e\u003c/param\u003e\n    /// \u003cparam name=\"lineCount\"\u003e\u003c/param\u003e\n    /// \u003creturns\u003e\u003c/returns\u003e\n    public static string CustomView(this DebugView sender, string[] tokens, int? lineCount)\n    {\n        var longViewLines = sender\n            .LongView.Split(new[] { Environment.NewLine }, StringSplitOptions.None);\n\n        StringBuilder builder = new();\n        if (lineCount.HasValue)\n        {\n            var result = longViewLines\n                .Where(item =\u003e item.Has(tokens))\n                .Take(lineCount.Value)\n                .ToArray();\n\n            foreach (var line in result)\n            {\n                builder.AppendLine(line.Contains(\"Unchanged\", StringComparison.OrdinalIgnoreCase) ?\n                    \"\" :\n                    line.TrimStart());\n            }\n        }\n\n        return builder.ToString();\n\n    }\n}\n```\n\n\n[^1]: [Entity Framework Core](https://docs.microsoft.com/en-us/ef/core/) \nEntity Framework (EF) Core is a lightweight, extensible, open source and cross-platform version of the popular Entity Framework data access technology.\n\n[^2]: [Migrations](https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/?tabs=dotnet-core-cli) Overview In real world projects, data models change as features get implemented: new entities or properties are added and removed, and database schemas need to be changed accordingly to be kept in sync with the application. The migrations feature in EF Core provides a way to incrementally update the database schema to keep it in sync with the application's data model while preserving existing data in the database.\n\n[^3]: Reverse Engineering an existing database with Microsoft command line tools or a Visual Studio extension like [EF Power Tools](https://marketplace.visualstudio.com/items?itemName=ErikEJ.EFCorePowerTools). There are other tools to reverse engineer databases, some a paid for and others which are free require knowledge of [T4 templates](https://docs.microsoft.com/en-us/visualstudio/modeling/code-generation-and-t4-text-templates?view=vs-2022).","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkarenpayneoregon%2Fmaster-ef-core","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkarenpayneoregon%2Fmaster-ef-core","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkarenpayneoregon%2Fmaster-ef-core/lists"}