-
Notifications
You must be signed in to change notification settings - Fork 494
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Combining custom camel case serializer with LINQ #810
Comments
The only issue I see with support both is the ambiguity of when the custom serializer is used vs the settings. Would having an option to set it directly on linq operation be better? That way the local linq setting always override the client level settings. |
A local LINQ setting would also work. It does seem a bit asymmetrical that the custom serializer is configured when the client is created while the camel case LINQ override is provided on each query. |
Here are some additional thoughts on how to handle this issue which may be relevant to users of the Cosmos SDK (people like me, not the developers of the SDK). I'm building my system in C# and I use the type system to assist me in doing that which includes using inheritance and combatting primitive obsession with dedicated value types. Unfortunately, there is some impedance mismatch between C# types and JSON. To handle this I have had to customize the JSON serializer and this customization has only grown over time. This has resulted in a heavy dependency on The most recent release of the Cosmos SDK has good support for camel case/pascal case but then I can no longer use my customized serializer. Essentially I was still stuck at
The fundamental problem here is that intersection of my domain model, my desire to use LINQ, a requirement that all JSON is camel cased to avoid client side confusion, and the Cosmos SDK is empty. Also, having a strong dependency on As Cosmos SDK works quite well for "simple" POCO types (especially with the latest addition to support camel case) I realized that I could solve my problem by inserting a "DTO layer" with "JSON friendly" types between my domain model and lower layers like JSON serialization, Cosmos SDK etc. This would remove all the trouble I'm having with using a specific JSON serializer and a specific Cosmos SDK. If I want camel case I can just generate the DTOs with camel case and handle that in my own mapper. I don't want to write a ton of DTOs by hand so instead I've created a system where "JSON friendly" DTOs are generated at run-time (using Roslyn). I already had a mapper in place to automatically map between domain types and DTOs and my DTO generator expands on specific conventions of my type system. Creating a general library to do this is a major undertaking so I have opted to just support the specific types I use to limit the scope. To sum up writing to Cosmos involves the following steps:
Reading is more or less the same just going the opposite way. The most tricky part is probably rewriting the "domain layer" LINQ expressions to equivalent "DTO layer" expressions which enables LINQ queries. I admit that there were far more devils found in the details than I expected when building this but I'm quite happy with the final results. |
@Liversage Really happy to see someone took the same path as me, albeit with a lot more thought. My clients are Dart and that means there's all kinds of issues with casing. I, too ended up with a DTO layer and doing my own mapping. In the end, it's just less voodoo and more predictable. I finally ended up writing a code generator that takes the C# DTO and turns it into a Dart-friendly DTO, which is what I dump back to the client. I was hoping the new SDK would allow me to get rid of the endless Thanks for taking the time to post. |
What really ended up helping me was combining
at the top of my models (instead of every property). And using:
Now things seem to get serialized properly at all levels. I also make use of inherited classes and the My parent class is an abstract, custom
LINQ based queries seem to work fine and I get back a heterogeneous list of objects (that are sub-classed from the abstract class) from a single query. |
bump |
When using a custom serializer with camelcase set, we found that we still had to use [JsonProperty] attributes, specifically on the property containing the partition key. When we didn't, calls to |
We really need this. It's insane that this is still open. I tried to work around it using custom type descriptors placing the json property attribute on the properties but the type descriptors aren't used. |
I just ran into this problem where the string values would come back correctly, but not the Guid or DateTime values. The where filters on Guid values would still work even though it wouldn't return the values. I tried adding I ended up adding |
I can confirm that |
This is should be fixed in 3.17.0 which should be released soon by PR: #2220 |
The SDK supports a custom serializer by deriving from
CosmosSerializer
but using a serializer that converts idiomatic C# pascal case property names to JSON camel case names break LINQ queries.Version 3.2.0-preview2 now supports
CosmosPropertyNamingPolicy.CamelCase
which fixes the camel case problem. Thanks!However, it is impossible to both have a custom serializer and also a LINQ provider that uses camel case. If I specify a custom serializer then I'm no longer allowed to use
CosmosPropertyNamingPolicy.CamelCase
which I need to change the behavior of the LINQ provider to match my custom serializer.Would it be possible to both configure the LINQ provider to generate camel case SQL while also using a custom serializer? That would be awesome.
Related issues: #72, #551, #570.
And just to explain why I need a custom serializer here are some of the reasons:
The text was updated successfully, but these errors were encountered: