### Configure Cosmos Repository with Options Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/1-getting-started Optionally provide a setup action to manually configure RepositoryOptions, including connection string, container ID, and database ID. ```csharp public void ConfigureServices(IServiceCollection services) { services.AddCosmosRepository( options => { options.CosmosConnectionString = "< connection string >"; options.ContainerId = "data-store"; options.DatabaseId = "samples"; }); } ``` -------------------------------- ### Configure Shared Container and Partitioning Strategy Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/1-getting-started/partioning This example shows how to configure two different item types, `Stock` and `StockRecord`, to share the same container named 'stock' and the same partition key path '/stockReferenceNumber'. This ensures that related items are stored in the same logical partition. ```csharp using Microsoft.Azure.CosmosRepository; var builder = WebApplication.CreateBuilder(args); builder.Services.AddCosmosRepository(options => { options.ContainerPerItemType = true; options.ContainerBuilder.Configure(userContainerOptions => { userContainerOptions.WithContainer("stock"); userContainerOptions.WithPartitionKey("/stockReferenceNumber"); }); options.ContainerBuilder.Configure(orderContainerOptions => { orderContainerOptions.WithContainer("stock"); orderContainerOptions.WithPartitionKey("/stockReferenceNumber"); }); }); var app = builder.Build(); app.MapGet("/", () => "Sample Inventory Partitioning Strategy"); app.Run(); ``` -------------------------------- ### Sequential Updates - OptimizeBandwidth On Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/3-item-types/etags When OptimizeBandwith is true, refetch the updated data each time to get the correct etag for subsequent updates. ```csharp TItem currentItem = _repository.CreateAsync(itemConfig); _repository.UpdateAsync(currentItem); currentItem = _repository.GetAsync(currentItem.Id); _repository.UpdateAsync(currentItem); currentItem = _repository.GetAsync(currentItem); currentItem = _repository.UpdateAsync(currentItem); ``` -------------------------------- ### Demonstrate Unique Key Policy Validation Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/6-miscellaneous/unique-keys This example shows how the unique key policies are enforced when creating items. It illustrates scenarios where creations succeed (different partition keys or different values) and where they fail due to unique key violations, resulting in a `CosmosException` with `HttpStatusCode.Conflict`. ```csharp IRepository repository = _serviceProvider.GetRequiredService>(); Person bobInYorkshire = new Person("bob", 20, "Yorkshire", "Blue"); repository.CreateAsync(bobInYorkshire); // This is in a different partition key range, so we can have another bob with the age of 20. Person bobInMerseyside = new Person("bob", 20, "Merseyside", "Green"); repository.CreateAsync(bobInMerseyside); // This is bob with a different age in Yorkshire so this does not violate the policy. Person bobInYorkshireWhoIs22 = new Person("bob", 22, "Yorkshire", "Red"); repository.CreateAsync(bobInYorkshireWhoIs22); try { //Fred does have a unique name and age, but he cannot also as Red as his favourite color. Person fredInYorkshireWhoAlsoLikeRed = new Person("fred", 30, "Yorkshire", "Red"); repository.CreateAsync(fredInYorkshireWhoAlsoLikeRed); } catch (CosmosException e) when (e.StatusCode is HttpStatusCode.Conflict) { //This is a violation of the key! } ``` -------------------------------- ### Configure Repository with Identity Authentication Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository Configure the repository to authenticate using Azure Active Directory identities. Ensure the Azure Identity NuGet package is installed. ```csharp using Azure.Identity; public void ConfigureServices(IServiceCollection services) { DefaultAzureCredential credential = new(); services.AddCosmosRepository( options => { options.TokenCredential = credential; options.AccountEndpoint = "< account endpoint URI >"; options.ContainerId = "data-store"; options.DatabaseId = "samples"; }); } ``` -------------------------------- ### Define Customer Partitioning Strategy with Attributes Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/1-getting-started/partioning This example demonstrates how to define a custom partitioning strategy for the `Customer` item type using attributes. The `[Container]` attribute specifies the container name as 'customers', and the `[PartitionKeyPath]` attribute sets the partition key path to '/emailAddress'. The `GetPartitionKeyValue` method is overridden to specify the property that holds the partition key value. ```csharp using Microsoft.Azure.CosmosRepository.Attributes; using Microsoft.Azure.CosmosRepository; [Container("customers")] [PartitionKeyPath("/emailAddress")] public class Customer : FullItem { public string EmailAddress { get; set; } protected override string GetPartitionKeyValue() => EmailAddress; } ``` -------------------------------- ### Configure Cosmos DB Repository with Identity Authentication Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/1-getting-started/authentication Use this configuration in your `Startup.cs` to authenticate with Azure Cosmos DB using an identity. Ensure you have the Azure Identity NuGet package installed. ```csharp using Azure.Identity; public void ConfigureServices(IServiceCollection services) { DefaultAzureCredential credential = new DefaultAzureCredential(); services.AddCosmosRepository( options => { options.TokenCredential = credential; options.AccountEndpoint = "< account endpoint URI >"; options.ContainerId = "data-store"; options.DatabaseId = "samples"; }); } ``` -------------------------------- ### Filter People by Birth Date using GetAsync Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/4-queries Use the `GetAsync` method with an expression to filter results. This example retrieves people born after a specific date. ```csharp public static class PeopleRepositoryExtensions { public static async Task> GetPeopleOlderThan( this IRepository repository, DateTime date) { return await repository.GetAsync(p => p.BirthDate > date); } public static async Task> GetPeopleWithoutMiddleNames(this IRepository repository) { IEnumerable peopleWithoutMiddleNames = await repository.GetAsync(p => p.MiddleName == null); return peopleWithoutMiddleNames; } } ``` -------------------------------- ### Implement an IItemChangeFeedProcessor Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/5-change-feed Implement the IItemChangeFeedProcessor interface to define how changes for a specific item type are processed. This example shows logging and conditional repository operations. ```csharp public class BookChangeFeedProcessor : IItemChangeFeedProcessor { private readonly ILogger _logger; private readonly IRepository _bookByIdReferenceRepository; public BookChangeFeedProcessor(ILogger logger, IRepository bookByIdReferenceRepository) { _logger = logger; _bookByIdReferenceRepository = bookByIdReferenceRepository; } public async ValueTask HandleAsync(Book rating, CancellationToken cancellationToken) { _logger.LogInformation("Change detected for book with ID: {BookId}", rating.Id); if (!rating.HasBeenUpdated) { await _bookByIdReferenceRepository .CreateAsync(new BookByIdReference(rating.Id, rating.Category), cancellationToken); } _logger.LogInformation("Processed change for book with ID: {BookId}", rating.Id); } } ``` -------------------------------- ### Define Multiple Unique Key Policies for Person Model Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/6-miscellaneous/unique-keys Use the `[UniqueKey]` attribute to define multiple unique key policies. Group properties by `keyName` to associate them with the same policy. This example defines a policy for 'nameAndAge' and another for 'favouriteColor'. ```csharp using Microsoft.Azure.CosmosRepository; using Microsoft.Azure.CosmosRepository.Attributes; namespace Sample.Models public class Person : Item { [UniqueKey(keyName: "nameAndAgePolicyKeyName", propertyPath: "/firstName")] public string FirstName { get; set; } [UniqueKey(keyName: "nameAndAgePolicyKeyName", propertyPath: "/age")] public int Age { get; set; } public string County { get; set; } [UniqueKey(keyName: "favouriteColorPolicyKeyName", propertyPath: "/favouriteColor")] public string FavouriteColor { get; set; } protected override string GetPartitionKeyValue() => County; public Person( string firstName, int age, string county, string favouriteColor) { FirstName = firstName; Age = age; County = county; FavouriteColor = favouriteColor; } } ``` -------------------------------- ### Define Item ID Property Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository This property defines the globally unique identifier for an item, defaulting to a new GUID. ```csharp [JsonProperty("id")] public string Id { get; set; } = Guid.NewGuid().ToString(); ``` -------------------------------- ### Get ETag after Create Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/3-item-types/etags When creating a new object, store the result from the create call to ensure you have the correct etag for future updates. ```csharp TItem currentItem = new TItem(...); currentItem = _repository.CreateAsync(currentItem); ``` -------------------------------- ### Configure Change Feed Monitoring for an Item Type Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/5-change-feed Configure change feed monitoring for a specific item type within the Cosmos DB repository setup. This is done via the IItemContainerBuilder. ```csharp WebApplicationBuilder builder = WebApplication.CreateBuilder(args); builder.Services.AddCosmosRepository(options => { options.DatabaseId = "change-feed-demo"; options.ContainerPerItemType = true; options.ContainerBuilder.Configure(containerOptions => { containerOptions.WithContainer(BookDemoConstants.Container); containerOptions.WithPartitionKey(BookDemoConstants.PartitionKey); //Listen to to the change feed containerOptions.WithChangeFeedMonitoring(); }); } ``` -------------------------------- ### Set Default Container TTL Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/3-item-types/time-to-live Configure a default Time To Live for all items within a container. This setting can be overridden at the item level. The example sets a default lifespan of 2 hours. ```csharp options.ContainerBuilder.Configure( x => x.WithContainerDefaultTimeToLive(TimeSpan.FromHours(2))); ``` -------------------------------- ### Override Item TTL Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/3-item-types/time-to-live Override the container's default Time To Live for a specific item. This example sets an item's lifespan to 4 hours, overriding the container's default of 2 hours. ```csharp BankAccount currentBankAccount = await repository.CreateAsync( new BankAccount() { Name = "Current Account", Balance = 500.0, TimeToLive = TimeSpan.FromHours(4) }); ``` -------------------------------- ### Basic Paging with Skip and Take Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/4-queries Demonstrates basic paging using `PageAsync` with `pageNumber` and `pageSize`. Be aware that this method can incur exponential RU charges on large datasets. ```csharp public class PagingExamples { public async Task BasicPageAsync(IRepository repository) { double totalCharge = 0; IPageQueryResult page = await repository.PageAsync(pageNumber: 1, pageSize: 25); while (page.HasNextPage) { foreach (Person person in page.Items) { Console.WriteLine(person); } totalCharge += page.Charge; page = await repository.PageAsync(pageNumber: page.PageNumber.Value + 1, pageSize: 25); Console.WriteLine($ ``` -------------------------------- ### Configure Repository Options in appsettings.json Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/1-getting-started Configure repository options such as connection string, database and container names, and performance settings using a JSON configuration file. ```json { "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*", "RepositoryOptions": { "CosmosConnectionString": "", "AccountEndpoint": "" "DatabaseId": "", "ContainerId": "", "OptimizeBandwidth": true, "ContainerPerItemType": true, "AllowBulkExecution": true, "SerializationOptions": { "IgnoreNullValues": true, "PropertyNamingPolicy": "CamelCase" } } } ``` -------------------------------- ### Simple Product Query by Category and Price Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/4-queries/specification-pattern Query products within a specific category, ordered by price from lowest to highest. Ensure the category ID is provided. ```csharp public class ProductSpecificationExamples { private class ProductsPriceLowestToHighestInCategory : DefaultSpecification { public ProductsPriceLowestToHighestInCategory(string categoryId) => Query .Where(x => x.PartitionKey == categoryId) .OrderBy(x => x.Price); } public async Task> RunDemoAsync(IRepository repository) { IQueryResult orderedProducts = await _productsRepository.QueryAsync(new ProductsPriceLowestToHighestInCategory("Clothing")); return orderedProducts; } } ``` -------------------------------- ### Default Partitioning Strategy Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/1-getting-started/partioning Configures the Azure Cosmos Repository with default settings, storing all IItem types in a single container with '/id' as the partition key. ```csharp using Microsoft.Azure.CosmosRepository; var builder = WebApplication.CreateBuilder(args); builder.Services.AddCosmosRepository(); var app = builder.Build(); app.MapGet("/", () => "Default Cosmos Repository Partitioning Strategy"); app.Run(); ``` -------------------------------- ### Continuation Token Paging for Cost-Effective Queries Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/4-queries Illustrates cost-effective paging using Cosmos DB continuation tokens. Provide the `continuationToken` from a previous response to resume paging. ```csharp public class PagingExamples { public async Task BasicScrollingAsync(IRepository repository) { double totalCharge = 0; IPage page = await repository.PageAsync(pageSize: 25, continuationToken: null); foreach (Person person in page.Items) { Console.WriteLine(person); } totalCharge += page.Charge; Console.WriteLine($"First 25 results cost {page.Charge}"); page = await repository.PageAsync(pageSize: 25, continuationToken: page.Continuation); foreach (Person person in page.Items) { Console.WriteLine(person); } totalCharge += page.Charge; Console.WriteLine($"Second 25 results cost {page.Charge}"); page = await repository.PageAsync(pageSize: 50, continuationToken: page.Continuation); foreach (Person person in page.Items) { Console.WriteLine(person); } totalCharge += page.Charge; Console.WriteLine($"Last 50 results cost {page.Charge}"); Console.WriteLine($"Total Charge {totalCharge} RU's"); } } ``` -------------------------------- ### Opt-in to Paging with Total Item Count Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/7-major-release-notes Pass `returnTotal: true` to the paging methods to include a count query for total items. Defaults to `false`. ```csharp _dogRepository.PageAsync( d => d.Breed == "cocker spaniel", pageNumber, pageSize, returnTotal: true); ``` -------------------------------- ### Custom Partitioning Strategy: Container Per Item Type Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/1-getting-started/partioning Enables a custom partitioning strategy where each IItem type is stored in its own container. This requires explicit configuration for each item type. ```csharp using Microsoft.Azure.CosmosRepository; var builder = WebApplication.CreateBuilder(args); builder.Services.AddCosmosRepository(options => { options.ContainerPerItemType = true; }); var app = builder.Build(); app.MapGet("/", () => "Custom Cosmos Repository Partitioning Strategy"); app.Run(); ``` -------------------------------- ### Define Custom Partition Key with PartitionKeyPathAttribute Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/1-getting-started This C# code defines a 'Person' item that uses a synthetic partition key. It demonstrates how to use the `PartitionKeyPathAttribute` to specify the partition key path and override `GetPartitionKeyValue` for custom partitioning logic. ```csharp using Microsoft.Azure.CosmosRepository; using Microsoft.Azure.CosmosRepository.Attributes; using Newtonsoft.Json; using System; namespace Example { [PartitionKeyPath("/synthetic")] public class Person : Item { public string FirstName { get; set; } = null!; public string? MiddleName { get; set; } public string LastName { get; set; } = null!; [JsonProperty("synthetic")] public string SyntheticPartitionKey => $"{FirstName}-{LastName}"; // Also known as a "composite key". protected override string GetPartitionKeyValue() => SyntheticPartitionKey; } } ``` -------------------------------- ### Add Cosmos Repository Health Checks with Custom Options Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/6-miscellaneous/healthchecks Configure custom health check options, including specific database and container IDs, by providing an options factory. ```csharp services.AddHealthChecks().AddCosmosRepository(optionsFactory: sp => new AzureCosmosDbHealthCheckOptions { DatabaseId = "my-database", ContainerIds = new[] { "Container1", "Container2" } }); ``` -------------------------------- ### Add Cosmos Repository Health Checks with Specific Assemblies Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/6-miscellaneous/healthchecks Refine health check scanning by providing specific assemblies containing your IItem types. This can reduce startup times. ```csharp services.AddHealthChecks().AddCosmosRepository(assemblies: typeof(ExampleItem).Assembly); ``` -------------------------------- ### Add In-Memory Cosmos Repository Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository Swap the standard AddCosmosRepository with AddInMemoryCosmosRepository to use an in-memory store for testing purposes. ```csharp services.AddInMemoryCosmosRepository() ``` -------------------------------- ### Advanced Product Query with Multiple Ordering Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/4-queries/specification-pattern Query products with multiple ordering clauses, first by price and then by name. Requires composite indexes for fields used in ThenBy/ThenByDescending. ```csharp public class ProductSpecificationAdvancedOrderingExamples { private class ProductsPriceLowestToHighestThenByName : DefaultSpecification { public ProductsPriceLowestToHighestInCategory(string categoryId) => Query .OrderBy(x => x.Price) .ThenByDescending(x => x.Name); } public async Task> RunDemoAsync(IRepository repository) { IQueryResult orderedProducts = await _productsRepository.QueryAsync(new ProductsPriceLowestToHighestThenByName()); return orderedProducts; } } ``` -------------------------------- ### Demonstrate unique key policy violation Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/6-miscellaneous/unique-keys When creating items, if a combination of properties defined in a unique key policy already exists within the same partition, a `CosmosException` with `HttpStatusCode.Conflict` will be thrown. Note that unique key policies are scoped to a partition key range. ```csharp IRepository repository = _serviceProvider.GetRequiredService>(); Person bobInYorkshire = new Person("bob", 20, "Yorkshire", "Blue"); repository.CreateAsync(bobInYorkshire); // This is in a different partition key range, so we can have another bob with the age of 20. Person bobInMerseyside = new Person("bob", 20, "Merseyside", "Green"); repository.CreateAsync(bobInMerseyside); // This is bob with a different age in Yorkshire so this does not violate the policy. Person bobInYorkshireWhoIs22 = new Person("bob", 22, "Yorkshire", "Red"); repository.CreateAsync(bobInYorkshireWhoIs22); try { //Adding another bob in Yorkshire violates the key. Person bobInYorkshire = new Person("bob", 20, "Yorkshire", "Yellow"); repository.CreateAsync(bobInYorkshire); } catch (CosmosException e) when (e.StatusCode is HttpStatusCode.Conflict) { //This is a violation of the key! } ``` -------------------------------- ### Configure Azure Cosmos DB Repository with appsettings.json Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/1-getting-started This JSON configuration is used for Azure Functions to set up the Cosmos DB repository connection details and options. Ensure you replace placeholder values with your actual Cosmos DB credentials and settings. ```json { "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*", "Values": { "RepositoryOptions:CosmosConnectionString": "", "RepositoryOptions:AccountEndpoint": "", "RepositoryOptions:DatabaseId": "", "RepositoryOptions:ContainerId": "", "RepositoryOptions:OptimizeBandwidth": true, "RepositoryOptions:ContainerPerItemType": true, "RepositoryOptions:AllowBulkExecution": true, "RepositoryOptions:SerializationOptions:IgnoreNullValues": true, "RepositoryOptions:SerializationOptions:PropertyNamingPolicy": "CamelCase" } } ``` -------------------------------- ### BankAccount Class Definition Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/3-item-types/time-to-live The demo BankAccount class implementation, inheriting from FullItem and including necessary attributes for Azure Cosmos DB. ```csharp using Microsoft.Azure.CosmosRepository; using Microsoft.Azure.CosmosRepository.Attributes; namespace OptimisticConcurrencyControl; [Container("accounts")] [PartitionKeyPath("/id")] public class BankAccount : FullItem { public string Name { get; set; } = string.Empty; public double Balance { get; set; } public void Withdraw(double amount) { if (Balance - amount < 0.0) throw new InvalidOperationException("Cannot go overdrawn"); Balance -= amount; } public void Deposit(double amount) { Balance += amount; } public override string ToString() => $"Account (Name = {Name}, Balance = {Balance}, Etag = {Etag})"; } ``` -------------------------------- ### Inject IRepository for Person Items Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/1-getting-started Request an instance of IRepository, specifying the type of item (e.g., Person), to interact with your data store. ```csharp using Microsoft.Azure.CosmosRepository; public class Consumer { readonly IRepository _repository; public Consumer(IRepository repository) => _repository = repository; // Use the repo... } ``` -------------------------------- ### Sequential Updates - OptimizeBandwidth Off Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/3-item-types/etags When OptimizeBandwith is false, use the result from the update method for subsequent updates to ensure the etag value is updated. ```csharp TItem currentItem = _repository.CreateAsync(itemConfig); currentItem = _repository.UpdateAsync(currentItem); currentItem = _repository.UpdateAsync(currentItem); ``` -------------------------------- ### Define a Person model with unique key attributes Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/6-miscellaneous/unique-keys Decorate properties with `[UniqueKey]` to define unique constraints. The `propertyPath` specifies the JSON property path for the unique key. ```csharp using Microsoft.Azure.CosmosRepository; using Microsoft.Azure.CosmosRepository.Attributes; namespace Sample.Models public class Person : Item { [UniqueKey(propertyPath: "/firstName")] public string FirstName { get; set; } [UniqueKey(propertyPath: "/age")] public int Age { get; set; } public string County { get; set; } public string FavouriteColor { get; set; } protected override string GetPartitionKeyValue() => County; public Person( string firstName, int age, string county, string favouriteColor) { FirstName = firstName; Age = age; County = county; FavouriteColor = favouriteColor; } } ``` -------------------------------- ### Use Default HealthChecks.CosmosDb Behavior Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/6-miscellaneous/healthchecks Set optionsFactory to null to use the default behavior of the HealthChecks.CosmosDb package, which only calls CosmosClient.ReadAccountAsync(). ```csharp services.AddHealthChecks().AddCosmosRepository(optionsFactory: null); ``` -------------------------------- ### Define a Person Item Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/1-getting-started Define your object graph by creating classes that inherit from the Item base class. Ensure all objects inherit from Item. ```csharp using Microsoft.Azure.CosmosRepository; public class Person : Item { public string FirstName { get; set; } public string LastName { get; set; } } ``` -------------------------------- ### Add Cosmos Repository to Service Collection Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/1-getting-started Use the AddCosmosRepository extension method to register the necessary services for the repository SDK. ```csharp public void ConfigureServices(IServiceCollection services) { services.AddCosmosRepository(); } ``` -------------------------------- ### Advanced Custom Partitioning: IItemContainerBuilder Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/1-getting-started/partioning Utilizes the IItemContainerBuilder to define specific containers and partition keys for different IItem types, such as 'Customer' and 'Order'. ```csharp using Microsoft.Azure.CosmosRepository; var builder = WebApplication.CreateBuilder(args); builder.Services.AddCosmosRepository(options => { options.ContainerPerItemType = true; options.ContainerBuilder.Configure(userContainerOptions => { userContainerOptions.WithContainer("customer"); userContainerOptions.WithPartitionKey("/emailAddress"); }); options.ContainerBuilder.Configure(orderContainerOptions => { orderContainerOptions.WithContainer("orders"); orderContainerOptions.WithPartitionKey("/customerId"); }); }); var app = builder.Build(); app.MapGet("/", () => "Sample e-commerce Partitioning Strategy"); app.Run(); ``` -------------------------------- ### Catch Mismatched ETag Errors Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/3-item-types/etags Catch CosmosException with HttpStatusCode.PreconditionFailed to handle cases where ETags do not match during an update. ```csharp try { currentBankAccount = await repository.UpdateAsync(currentBankAccount); Console.WriteLine($"Updated bank account: {currentBankAccount}."); } catch (CosmosException exception) when (exception.StatusCode == HttpStatusCode.PreconditionFailed) { Console.WriteLine("Failed to update balance as the etags did not match."); } ``` -------------------------------- ### Add Cosmos Repository Health Checks Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/6-miscellaneous/healthchecks Use this to add default Cosmos DB health checks. It scans all assemblies for IItem types. ```csharp services.AddHealthChecks().AddCosmosRepository(); ``` -------------------------------- ### Override Item Time To Live Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository Set a specific Time To Live for an individual item, overriding the container's default TTL. ```csharp BankAccount currentBankAccount = await repository.CreateAsync( new BankAccount() { Name = "Current Account", Balance = 500.0, TimeToLive = TimeSpan.FromHours(4) }); ``` -------------------------------- ### Define a Custom Item Type Inheriting from Item Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/3-item-types Inherit from the base `Item` type to define a custom model for storage in Cosmos DB. Override `GetPartitionKeyValue` to specify the partition key value. ```csharp public class Product : Item { public string Name { get; set; } public string CategoryId { get; set; } public string PartitionKey { get; set; } public double Price { get; set; } public StockInformation Stock { get; set; } protected override string GetPartitionKeyValue() => CategoryId; } ``` -------------------------------- ### Pass ETag to Patch Update Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/3-item-types/etags Provide the etag when performing a patch update to specific properties of an item. ```csharp await repository.UpdateAsync(currentBankAccount.Id, builder => builder.Replace(account => account.Balance, currentBankAccount.Balance - 250), etag: currentBankAccount.Etag); ``` -------------------------------- ### Stream Parcels with Delivery Region ID Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/4-queries Use IAsyncEnumerable to stream parcels based on a delivery region ID, supporting pagination with continuation tokens. This is useful for handling large result sets without loading all data into memory. ```csharp public class ParcelRepository { private readonly IRepository _parcelCosmosRepository; public ParcelRepository(IRepository parcelCosmosRepository) => _parcelCosmosRepository = parcelCosmosRepository; public async IAsyncEnumerable StreamParcelsWithDeliveryRegionId( string deliveryRegionId, int max, int chunkSize = 25, [EnumeratorCancellation] CancellationToken cancellationToken = default) { int collected = 0; bool hasMoreResults = true; string? token = null; Expression> expression = parcel => parcel.PartitionKey == deliveryRegionId && parcel.Status == ParcelStatus.Inducted; while (hasMoreResults && collected < max) { var page = await _parcelCosmosRepository .PageAsync(expression, chunkSize, token, cancellationToken); token = page.Continuation; hasMoreResults = page.Continuation is not null; foreach (var item in page.Items) { if (collected < max) { yield return item; } collected++; } } } } ``` -------------------------------- ### Define Item Type Property Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository This property indicates the subclass name, used for implicit filtering. ```csharp [JsonProperty("type")] public string Type { get; set; } ``` -------------------------------- ### Map Health Checks Endpoint Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/6-miscellaneous/healthchecks Map the health check endpoint to a specific URL path in your ASP.NET Core application. ```csharp app.MapHealthChecks("/healthz"); ``` -------------------------------- ### Ignore ETag During Update Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/3-item-types/etags Bypass the etag check during an update operation by setting the 'ignoreEtag' optional parameter to true. ```csharp await repository.UpdateAsync(currentBankAccount, ignoreEtag: true); ``` -------------------------------- ### Disable Item Expiration Source: https://ievangelist.github.io/azure-cosmos-dotnet-repository/3-item-types/time-to-live Prevent a specific item from ever expiring by setting its Time To Live to -1 seconds. This effectively disables TTL for that item. ```csharp BankAccount currentBankAccount = await repository.CreateAsync( new BankAccount() { Name = "Current Account", Balance = 500.0, TimeToLive = TimeSpan.FromSeconds(-1) }); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.