[CSHARP-1948] LINQ translation error when RegisterSerializer was called with a serializer for the wrong value type Created: 20/Mar/17  Updated: 05/Apr/19  Resolved: 21/Mar/17

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

Type: Task Priority: Major - P3
Reporter: Gushchin Anton Assignee: Robert Stam
Resolution: Done Votes: 0
Labels: question
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
is related to CSHARP-1949 BsonSerializer RegisterSerializer sho... Closed

 Description   

mongocsharpdriver 2.4.2

Sample:

namespace ConsoleApplication
{
    using System;
    using System.Linq;
 
    using MongoDB.Bson.Serialization.Serializers;
    using MongoDB.Driver;
 
    class Program
    {
        static void Main(string[] args)
        {
            MongoDB.Bson.Serialization.BsonSerializer.RegisterSerializer(typeof(DateTime), new DateTimeSerializer(DateTimeKind.Local));
            MongoDB.Bson.Serialization.BsonSerializer.RegisterSerializer(typeof(DateTime?), new DateTimeSerializer(DateTimeKind.Local));
 
            new MongoClient("mongodb://localhost/testdb")
                .GetDatabase("testdb")
                .GetCollection<TestItem>(typeof(TestItem).Name)
                .AsQueryable()
                .Count(e => e.Date == null);
        }
    }
    
    public sealed class TestItem
    {
        public Guid Id { get; set; }
        
        public DateTime? Date { get; set; }
    }
}

Exception:

An unhandled exception of type 'System.InvalidOperationException' occurred in System.Core.dll
 
Additional information: The operands for operator 'Equal' do not match the parameters of method 'op_Equality'.
 
   at System.Linq.Expressions.Expression.GetMethodBasedBinaryOperator(ExpressionType binaryType, Expression left, Expression right, MethodInfo method, Boolean liftToNull)
   at System.Linq.Expressions.Expression.Equal(Expression left, Expression right, Boolean liftToNull, MethodInfo method)
   at System.Linq.Expressions.Expression.MakeBinary(ExpressionType binaryType, Expression left, Expression right, Boolean liftToNull, MethodInfo method, LambdaExpression conversion)
   at System.Linq.Expressions.BinaryExpression.Update(Expression left, LambdaExpression conversion, Expression right)
   at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
   at MongoDB.Driver.Linq.Processors.SerializationBinder.VisitBinary(BinaryExpression node)
   at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)
   at MongoDB.Driver.Linq.Processors.SerializationBinder.Visit(Expression node)
   at MongoDB.Driver.Linq.Processors.PipelineBindingContext.Bind(Expression node)
   at MongoDB.Driver.Linq.Processors.BinderHelper.BindWhere(PipelineExpression pipeline, IBindingContext bindingContext, LambdaExpression lambda)
   at MongoDB.Driver.Linq.Processors.Pipeline.MethodCallBinders.CountBinder.Bind(PipelineExpression pipeline, PipelineBindingContext bindingContext, MethodCallExpression node, IEnumerable`1 arguments)
   at MongoDB.Driver.Linq.Processors.MethodInfoMethodCallBinder`1.Bind(PipelineExpression pipeline, TBindingContext bindingContext, MethodCallExpression node, IEnumerable`1 arguments)
   at MongoDB.Driver.Linq.Processors.PipelineBinderBase`1.BindMethodCall(MethodCallExpression node)
   at MongoDB.Driver.Linq.Processors.PipelineBinderBase`1.Bind(Expression node)
   at MongoDB.Driver.Linq.Processors.Pipeline.PipelineBinder.Bind(Expression node, IBsonSerializerRegistry serializerRegistry)
   at MongoDB.Driver.Linq.MongoQueryProviderImpl`1.Prepare(Expression expression)
   at MongoDB.Driver.Linq.MongoQueryProviderImpl`1.Translate(Expression expression)
   at MongoDB.Driver.Linq.MongoQueryProviderImpl`1.Execute(Expression expression)
   at MongoDB.Driver.Linq.MongoQueryProviderImpl`1.Execute[TResult](Expression expression)
   at System.Linq.Queryable.Count[TSource](IQueryable`1 source, Expression`1 predicate)
   at ConsoleApplication11.Program.Main(String[] args) in c:\users\gushin\documents\visual studio 2015\Projects\ConsoleApplication11\ConsoleApplication11\Program.cs:line 16
   at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()



 Comments   
Comment by Robert Stam [ 21/Mar/17 ]

Created ticket for driver to validate serializer argument to RegisterSerializer at runtime.

Comment by Robert Stam [ 21/Mar/17 ]

The problem lies with the second serializer you registered. You are registering a serializer for values of type DateTime?, but the actual serializer you provided is for values of type DateTime.

It is unfortunate that the driver is not checking that the supplied serializer is for the correct value type. If it was, the error would have been caught much sooner. Since it's not, it just results in an unexpected error later on due to the mismatch.

I recommend that you use the type safe overloads of RegisterSerializer, so that the type mismatch can be caught at compile time. The following snippet also shows you how to create a serializer for values of the nullable DateTime? type.

BsonSerializer.RegisterSerializer<DateTime>(new DateTimeSerializer(DateTimeKind.Local));
BsonSerializer.RegisterSerializer<DateTime?>(new NullableSerializer<DateTime>(new DateTimeSerializer(DateTimeKind.Local)));

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