Skip to content
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

Error converting type: Bug or implementation issue - please help #158

Open
jacodv opened this issue Oct 27, 2022 · 3 comments
Open

Error converting type: Bug or implementation issue - please help #158

jacodv opened this issue Oct 27, 2022 · 3 comments

Comments

@jacodv
Copy link

jacodv commented Oct 27, 2022

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
image

@jacodv
Copy link
Author

jacodv commented Oct 27, 2022

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);
    }

@evaanp
Copy link

evaanp commented Jun 12, 2023

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.

@jacodv
Copy link
Author

jacodv commented Jun 12, 2023

I did not. I reverted to getting the actual query from the provider, in my case MongoDB. Then I recreate the IQueryable 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants