[CSHARP-4634] Error in LINQ3 provider when custom ObjectSerializer is used Created: 04/May/23  Updated: 28/Oct/23  Resolved: 23/May/23

Status: Closed
Project: C# Driver
Component/s: None
Affects Version/s: None
Fix Version/s: 2.19.2

Type: Bug Priority: Unknown
Reporter: Gian Maria Ricci Assignee: Oleksandr Poliakov
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: PNG File 2023-05-04_15-55-02.png     PNG File image-2023-05-10-14-44-32-999.png    
Backwards Compatibility: Fully Compatible
Documentation Changes: Not Needed
Documentation Changes Summary:

1. What would you like to communicate to the user about this feature?
2. Would you like the user to see examples of the syntax and/or executable code and its output?
3. Which versions of the driver/connector does this apply to?


 Description   

Summary

version 2.19 of C# Driver.

With new LINQ3 provider, if you use a custom ObjectSerializer like Elsa does (https://github.com/elsa-workflows/elsa-core/blob/047c51d7cf7b8a3230353e3518439704756ca95b/src/persistence/Elsa.Persistence.MongoDb/Serializers/ObjectSerializer.cs) you incurr in an error when you execute any LINQ query based on new LINQ3 provider

 ---> System.InvalidCastException: Unable to cast object of type 'Elsa.Persistence.MongoDb.Serializers.ElsaObjectSerializer' to type 'MongoDB.Bson.Serialization.Serializers.ObjectSerializer'.
   at MongoDB.Bson.Serialization.Serializers.DiscriminatedInterfaceSerializer`1..ctor(IDiscriminatorConvention discriminatorConvention, IBsonSerializer`1 interfaceSerializer)
   at MongoDB.Bson.Serialization.Serializers.DiscriminatedInterfaceSerializer`1..ctor(IDiscriminatorConvention discriminatorConvention)
   at MongoDB.Bson.Serialization.Serializers.DiscriminatedInterfaceSerializer`1..ctor()

How to Reproduce

It is sufficient to declare a custom object serializer, like elsa does (https://github.com/elsa-workflows/elsa-core/blob/047c51d7cf7b8a3230353e3518439704756ca95b/src/persistence/Elsa.Persistence.MongoDb/Serializers/ObjectSerializer.cs) register the serializer, persists some objects and then issue a LINQ query to retrieve. If you look at the attached image, in the constructor of  DiscriminatedInterfaceSerializer class, the driver is looking for MongoDb serializer for object but it CAST immeditaly to ObjectSerializer, thus preventing anyone from registering own serializer for object class.

Additional Background

Look at attached image.



 Comments   
Comment by Githook User [ 24/May/23 ]

Author:

{'name': 'Oleksandr Poliakov', 'email': '31327136+sanych-sun@users.noreply.github.com', 'username': 'sanych-sun'}

Message: CSHARP-4634: Error in LINQ3 provider when custom ObjectSerializer is used (#1080)
Branch: v2.19.x
https://github.com/mongodb/mongo-csharp-driver/commit/513d0ce685354b183779cc49e02243daba4f136c

Comment by Githook User [ 23/May/23 ]

Author:

{'name': 'Oleksandr Poliakov', 'email': '31327136+sanych-sun@users.noreply.github.com', 'username': 'sanych-sun'}

Message: CSHARP-4634: Error in LINQ3 provider when custom ObjectSerializer is used (#1080)
Branch: master
https://github.com/mongodb/mongo-csharp-driver/commit/43f99178442c2f3cacd2738142de18b540de7afd

Comment by Oleksandr Poliakov [ 10/May/23 ]

Hi alkampfer@nablasoft.com .

Thank you for the provided code, it helped a lot! So here is the minimal code to reproduce the problem:

var collection = db.GetCollection<WorkflowDefinition>("WorkflowDefinition");
var result = collection.AsQueryable()
    .Where(w => ((ITenantScope)w).TenantId == "abc")
    .Count(); 

Cast to an interface somehow causes the problem. This is definitely a bug in LINQ provider. I will continue investigating the problem and keep you posted.

Comment by Gian Maria Ricci [ 10/May/23 ]

Hi oleksandr.poliakov@mongodb.com 

actually I struggled to reproduce in a simple project, it seems that is triggered by some special condition that happens inside elsa.workflow, but you have a repro here https://github.com/alkampfergit/MongoDbNewDriverTest/tree/master/2.19 in that folder you can find a project that generates the bug using the LINQ3 provider and works perfectly with LINQ2 provider. It uses Elsa.Workflow internal classes but it is a really simple repro that you can run.

You do not need to have test data in database, it raises exception even is the collection does not exists / is empty, just run the sample and you will get the exception.

The error is inside class DiscriminatedInterfaceSerializer line 84, where the mongodb-csharp-driver performs a LookupSerializer but instead of casting to the interface will cast into internal specific implementation. I was able to reproduce using only elsa original class, but with the repro it is possible to investigate the problem.

Comment by Oleksandr Poliakov [ 09/May/23 ]

Hey alkampfer@nablasoft.com

Thanks for reporting this issue. We cannot reproduce the issue as per provided steps to reproduce, the exception suggests that some cast to an interface should be involved. Could you please provide a minimal reproducible example to help us debug it? 

Thanks

Comment by Service Account: DBX TPM [ 04/May/23 ]

Hi alkampfer@nablasoft.com, thank you for reporting this issue! The team will look into it and get back to you soon.

Generated at Wed Feb 07 21:48:50 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.