IEvangelist / azure-cosmos-dotnet-repository

Wraps the .NET SDK for Azure Cosmos DB abstracting away the complexity, exposing a simple CRUD-based repository pattern
https://ievangelist.github.io/azure-cosmos-dotnet-repository
MIT License
300 stars 89 forks source link

UseStrictTypeChecking ContainerOption is ignored when using DefaultRepository.Specs #452

Closed GuyDigital closed 2 months ago

GuyDigital commented 2 months ago

Configuring a Repository ContainerOptions with .WithoutStrictTypeChecking() STILL appends type checking to specification queries

Reproducing The Issue

builder.Services.AddCosmosRepository(options => 
{
    options.ContainerBuilder.Configure<ExampleModel>(containerOptions => containerOptions
        .WithoutStrictTypeChecking()
        .WithContainer("Example")
        .WithPartitionKey("/id"));
};
public class ExampleSpecification : DefaultSpecification<ExampleModel>
{
    public ExampleSpecification() =>
        Query
            .Where(q => q.Category == "Red");
}

Main.cs

var queryResult = await _cosmosRepository.QueryAsync(new ExampleSpecification());

Console Logged Expected Query

"SELECT TOP 25 VALUE root FROM root WHERE (root[\"category\"] = \"Red\")"

Console Logged Actual Query

"SELECT TOP 25 VALUE root FROM root WHERE (((NOT IS_DEFINED(root[\"type\"])) OR (root[\"type\"] = \"ExampleModel\")) AND (root[\"category\"] = \"Red\"))"

In my case I need to retrieve all "Red" objects in the given collection as "ExampleModel"s, but all of my models are stored as type "OtherModel". The actual query requires "type" exactly match "ExampleModel" or is not defined. So when executed, the actual query does not retrieve anything.

Environment summary SDK Version: 8.1.5 OS Version: Windows

Additional context This is the case since DefaultRepository.Specs uses DefaultRepositoryExpressionProvider.Default() which does not check UseStrictTypeChecking like Build() does for other DefaultRepository Operations.

To test, in DefaultRepository.Specs I replaced repositoryExpressionProvider.Default<TItem>() with repositoryExpressionProvider.Build<TItem>(_ => true) and produced the expected query. The popper way to fix this would probably be fixing Default() in the ExpressionProvider to work more similarly to Build().