Error converting type: Bug or implementation issue - please help
Describe the bug
We have a generic report generator, it receives IQueryable<T> and OData query string. I need to change it to accept IQueryable<T> and Expression.
The report engine must execute
var results = records.Provider.CreateQuery<T>(expression);
Below is a simple test
To Reproduce
- Dotnet 6
[Test]
public void CreateQuery_GivenExpression_ShouldGenerateReport()
{
// arrange
Setup();
var emptyList = new List<OutputChannelLog>().AsQueryable();
var query = emptyList.Where(x => x.Channel == OutputChannelCodes.Email);
var expression = query.Expression;
var settings = new FactorySettings(){UseRelaxedTypeNames = true};
var expressionSerializer = new ExpressionSerializer(new JsonSerializer(), settings);
var expressionText = expressionSerializer.SerializeText(expression);
Console.WriteLine(@$"Expression: {expression}");
Console.WriteLine(@$"ExpressionText: {expressionText}");
var user = Builder<User>.CreateNew().WithValidData().Build();
var dbItems = Builder<OutputChannelLog>
.CreateListOfSize(4)
.TheFirst(2)
.With(x => x.Channel = OutputChannelCodes.Sms)
.TheNext(2)
.With(x => x.Channel = OutputChannelCodes.Email)
.Build();
var dbQuery = dbItems.AsQueryable();
// action
var reportItems = dbQuery.Provider.CreateQuery<OutputChannelLog>(expressionSerializer.DeserializeText(expressionText));
// assert
reportItems.Count().Should().Be(2);
}
Expected behavior Filter the records from 4 to 2
Screenshots

I have also tried a simple type with the DataContract attribute. But adding the [Datacontract] attribute to all our models are not an option if that was the requirement.
** Simple Type **
[DataContract]
public class OutputChannelLogTest
{
public string CreatedBy { get; set; }
public string Channel { get; set; }
}
Updated Test
[Test]
public void CreateQuery_GivenExpression_ShouldGenerateReport()
{
// arrange
Setup();
var emptyList = new List<OutputChannelLogTest>().AsQueryable();
var query = emptyList.Where(x => x.Channel == "Email");
var expression = query.Expression;
var settings = new FactorySettings(){UseRelaxedTypeNames = true};
var expressionSerializer = new ExpressionSerializer(new JsonSerializer(), settings);
var expressionText = expressionSerializer.SerializeText(expression);
Console.WriteLine(@$"Expression: {expression}");
Console.WriteLine(@$"ExpressionText: {expressionText}");
var dbItems = Builder<OutputChannelLogTest>
.CreateListOfSize(4)
.TheFirst(2)
.With(x => x.Channel = "Sms")
.TheNext(2)
.With(x => x.Channel = "Email")
.Build();
var dbQuery = dbItems.AsQueryable();
// action
var reportItems = dbQuery.Provider.CreateQuery<OutputChannelLogTest>(
expressionSerializer.DeserializeText(expressionText));
// assert
reportItems.Count().Should().Be(2);
}
Did you find a solution for this? I get this error when serializing an expression with an StringComparison enum in it.
Edit: I found the solution. There is an AddKnownType method in every serializer.
I did not. I reverted to getting the actual query from the provider, in my case MongoDB. Then I recreate the IQueryable<T> from the actual query and work with the result.
Look at Remote.Linq. I came close to solving the problem with that package, but still not all the permutations.