{"id":13628866,"url":"https://github.com/StevenThuriot/TableStorage","last_synced_at":"2025-04-17T04:32:30.646Z","repository":{"id":86679476,"uuid":"514586825","full_name":"StevenThuriot/TableStorage","owner":"StevenThuriot","description":"Streamlined way of working with Azure Data Tables that mimics Entity Framework's way of working with DbSets. Source Generators for the Table Entities to avoid any reflection calls being made, making it easier to use Azure Data Tables in a NativeAOT project.","archived":false,"fork":false,"pushed_at":"2025-03-28T11:52:58.000Z","size":206,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-28T12:34:54.712Z","etag":null,"topics":["azure","storage","table"],"latest_commit_sha":null,"homepage":"https://www.nuget.org/packages/TableStorage/","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/StevenThuriot.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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-07-16T13:33:18.000Z","updated_at":"2025-03-07T10:57:09.000Z","dependencies_parsed_at":"2024-04-23T12:11:29.229Z","dependency_job_id":"77b38bd7-48cf-4d80-a1e3-157d4d188d55","html_url":"https://github.com/StevenThuriot/TableStorage","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/StevenThuriot%2FTableStorage","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StevenThuriot%2FTableStorage/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StevenThuriot%2FTableStorage/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StevenThuriot%2FTableStorage/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/StevenThuriot","download_url":"https://codeload.github.com/StevenThuriot/TableStorage/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249315998,"owners_count":21249871,"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":["azure","storage","table"],"created_at":"2024-08-01T22:00:58.678Z","updated_at":"2025-04-17T04:32:30.639Z","avatar_url":"https://github.com/StevenThuriot.png","language":"C#","readme":"﻿# TableStorage\nStreamlined way of working with Azure Data Tables\n\n## Installation\n\n```bash\ndotnet add package TableStorage\n```\n\n## Usage\n\nCreate your own TableContext and mark it with the `[TableContext]` attribute. This class must be partial.\n\n```csharp\n[TableContext]\npublic partial class MyTableContext;\n```\n\nCreate your models, these must be classes and have a parameterless constructor. Mark them with the `[TableSet]` attribute. This class must be partial.\n\n```csharp\n[TableSet]\npublic partial class Model\n{\n    public string Data { get; set; }\n    public bool Enabled { get; set; }\n}\n```\n\nProperties can also be defined using the `[TableSetProperty]` attribute. \nThis is particularly useful if you are planning on using dotnet 8+'s Native AOT, as the source generation will make sure any breaking reflection calls are avoided by the Azure.Core libraries.\nStarting C# 13, you can also mark them as partial.\n\n```csharp\n[TableSet]\n[TableSetProperty(typeof(string), \"Data\")]\n[TableSetProperty(typeof(bool), \"Enabled\")]\npublic partial class Model;\n```\n\nSome times it's also nice to have a pretty name for your `PartitionKey` and `RowKey` properties, as the original names might not always make much sense when reading your code, at least not in a functional way.\nYou can use the `PartitionKey` and `RowKey` properties of `TableSet` to create a proxy for these two properties.\n\n```csharp\n[TableSet(PartitionKey = \"MyPrettyPartitionKey\", RowKey = \"MyPrettyRowKey\")]\npublic partial class Model;\n```\n\n`TableSet` also has `TrackChanges` property, default `false`, that will try to optimize what is being sent back to the server when making changes to an entity.\nWhen tracking changes, it's important to either use the `TableSetProperty` attribute to define your properties, or mark them as partial starting C# 13.\n\n```csharp\n[TableSet]\n[TableSetProperty(typeof(string), \"Data\")]\npublic partial class Model\n{\n    public partial bool Enabled { get; set; }\n}\n```\n\nPlace your tables on your TableContext. The sample below will create 2 tables in table storage, named Models1 and Models2.\n\n```csharp\n[TableContext]\npublic partial class MyTableContext\n{\n    public TableSet\u003cModel\u003e Models1 { get; set; }\n    public TableSet\u003cModel\u003e Models2 { get; set; }\n}\n```\n\nRegister your TableContext in your services. An extension method will be available specifically for your context.\n\n```csharp\nbuilder.Services.AddMyTableContext(builder.Configuration.GetConnectionString(\"MyConnectionString\"));\n```\n\nOptionally, pass along a `Configure` method to adjust some configuration options.\n\n```csharp\nbuilder.Services.AddMyTableContext(builder.Configuration.GetConnectionString(\"MyConnectionString\"), Configure);\n\nstatic void Configure(TableOptions options)\n{\n    options.AutoTimestamps = true;\n    options.TableMode = TableUpdateMode.Merge;\n}\n```\n\nInject `MyTableContext` into your class and use as needed.\n\n```csharp\npublic class MyService(MyTableContext context)\n{\n    private readonly MyTableContext _context = context;\n\n    public async Task DoSomething(CancellationToken token)\n    {\n        var entity = await _context.Models1.GetEntityOrDefaultAsync(\"partitionKey\", \"rowKey\", token);\n        if (entity is not null)\n        {\n            //Do more\n        }\n    }\n}\n```\n\nFor some special cases, your table name might not be known at compile time. To handle those, an extension method has been added:\n\n```csharp\nvar tableSet = context.GetTableSet\u003cModel\u003e(\"randomname\");\n```\n\n## Linq\n\nA few simple Linq extension methods have been provided in the `TableStorage.Linq` namespace that optimize some existing LINQ methods specifically for Table Storage.\n\nSince these return an instance that implements `IAsyncEnumerable`, `System.Linq.Async` is an excellent companion to these methods. Do keep in mind that as soon as you start using `IAsyncEnumerable`, any further operations will run client-side.\n\n\nNote: `Select` will include the actual transformation. If you want the original model, with only the selected fields retrieved, use `SelectFields` instead.\nIf you are using Native AOT, you will need to use `SelectFields` as `Select` will not work.\n","funding_links":[],"categories":["Content","Source Generators"],"sub_categories":["142. [TableStorage](https://ignatandrei.github.io/RSCG_Examples/v2/docs/TableStorage) , in the [Database](https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg-examples#database) category","Database / ORM"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FStevenThuriot%2FTableStorage","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FStevenThuriot%2FTableStorage","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FStevenThuriot%2FTableStorage/lists"}