question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

LINQ-constructed document queries ignore Json annotations based on type constraint

See original GitHub issue

Describe the bug When using LINQ to create queries in a generic function with a constraint on the document’s type parameter, the query generator ignores annotations on the concrete type. Specifically, the generator ignores Json serialization annotations on the properties, leading to incorrect queries.

To Reproduce

using System;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using Microsoft.Azure.Cosmos;
using Microsoft.Azure.Cosmos.Fluent;
using Newtonsoft.Json;

namespace ConsoleApp
{
    interface ITest
    {
        string Id { get; set; }
        
        string Name { get; set; }
    }

    class Test : ITest
    {
        [JsonProperty("id")] 
        public string Id { get; set; }
        
        [JsonProperty("myweirdnameproperty")] 
        public string Name { get; set; }
    }
    
    class Program
    {
        static async Task Main(string[] args)
        {
            
            var client = new CosmosClientBuilder("AccountEndpoint=https://localhost:8081/;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==").Build();
            
            
            var databaseResp = await client.GetDatabase("testdb").ReadAsync();
            var database = databaseResp.StatusCode == HttpStatusCode.OK
                ? databaseResp.Database
                : (await client.CreateDatabaseAsync("testdb")).Database;
            
            var containerResp = await database.GetContainer("testcontainer").ReadContainerAsync();
            var container = containerResp.StatusCode == HttpStatusCode.OK
                ? containerResp.Container
                : (await database.CreateContainerAsync(new ContainerProperties("testcontainer", "/id"))).Container;
            
            
            InterfaceConstraint<Test>(container);
            ClassConstraint<Test>(container);
        }

        private static void InterfaceConstraint<T>(Container container)
        where T :  ITest
        {
            Console.WriteLine($"InterfaceConstraint Query for T = \"{typeof(T)}\": {container.GetItemLinqQueryable<T>().Select(doc => doc.Name).ToSqlQueryText()}");
        }
        
        private static void ClassConstraint<T>(Container container)
            where T :  Test
        {
            Console.WriteLine($"ClassConstraint Query for T = \"{typeof(T)}\": {container.GetItemLinqQueryable<T>().Select(doc => doc.Name).ToSqlQueryText()}");
        }
    }    
}

Expected behavior

Query generator should consider annotation on Test class. Expected output:

InterfaceConstraint Query for T = "ConsoleApp.Test": SELECT VALUE root["myweirdnameproperty"] FROM root
ClassConstraint Query for T = "ConsoleApp.Test": SELECT VALUE root["myweirdnameproperty"] FROM root

Actual behavior

Query generator ignores annotation on Test class. Actual output:

InterfaceConstraint Query for T = "ConsoleApp.Test": SELECT VALUE root["Name"] FROM root
ClassConstraint Query for T = "ConsoleApp.Test": SELECT VALUE root["myweirdnameproperty"] FROM root

Environment summary SDK Version: Microsoft.Azure.WebJobs.Extensions.CosmosDB 3.0.3, .NET Core 2.2 OS Version: Windows 10,

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:5
  • Comments:11 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
thomaslevesquecommented, Oct 23, 2020

Workaround, until this is fixed: apply the JsonProperty attributes on the interface properties. It’s ugly, but it works. (in addition to the class, otherwise other things will break…)

2reactions
j82wcommented, Jun 15, 2020

@bchong95 can you take a look?

Read more comments on GitHub >

github_iconTop Results From Across the Web

DocumentClient.CreateDocumentQuery ...
JsonSerializerSettings are being ignored when creating a query using CreateDocumentQuery and LINQ/ IOrderedQueryable . Environment summary. SDK ...
Read more >
Constraints on type parameters - C# Programming Guide
Learn about constraints on type parameters. Constraints tell the compiler what capabilities a type argument must have.
Read more >
Microsoft® ADO.NET 4 Step by Step
DataColumn definitions include a data type declaration based on the kind of data destined for each column. For instance, a CustomerLastName.
Read more >
Validation with Hibernate Validator
Constraints are added on fields, and when an object is validated, the values are checked. The getter and setter methods are also used...
Read more >
where (generic type constraint) - C# Reference
Constraints can specify interfaces, base classes, or require a generic type to be a reference, value, or unmanaged type. They declare ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found