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

Problem with Query over JObject, Filter with SubProperty not returning the correct value #415

Closed
luizfbicalho opened this issue Aug 24, 2020 · 9 comments
Assignees
Labels

Comments

@luizfbicalho
Copy link

luizfbicalho commented Aug 24, 2020

I created this console application to reproduce my problem

       static void Main(string[] args)
        {
            var obj = new object[] {
               new { Id= 36,
                Descricao= "Responsiva",
                Tipo=new  { Id= "1" },TipoId=  "1" ,
                Custo= 160
              },
              new {
                Id= 31,
                Descricao= "Log",
                Tipo= new { Id= "1" },TipoId=  "1" ,
                Custo= 0
              },
              new {
                Id= 32,
                Descricao= "Multi-Idioma",
                Tipo= new { Id= "2" },TipoId=  "2" ,
                Custo= 2
              },
              new {
                Id= 33,
                Descricao= "Tela Administrativa",
                Tipo= new { Id= "2" },TipoId=  "2" ,
                Custo= 8
              }
            };


            var json = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
            var dados = Newtonsoft.Json.JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JObject[]>(json);

            var retorno = dados.AsQueryable()
                               .Select("new (  string(Id) as Id, string(Descricao) as Descricao,new (  string(Id) as Id)  as Tipo, string(TipoId) as TipoId, string(Custo) as Custo)");
            retorno = retorno.OrderBy("Descricao asc");

            var retorno1 = retorno.Where("(TipoId = @0)", "1");
            var retorno2 = retorno.Where("(Tipo.Id = @0)", "1");

            Console.WriteLine(retorno.Count());
            Console.WriteLine(retorno1.Count());
            Console.WriteLine(retorno2.Count());
            Console.ReadLine();

        }

If you look at the results , the count should be the same, but for some reason, retorno2 is filtering for the Root Id of the object, and not the Tipo property and Id SubProperty

@JonathanMagnan JonathanMagnan self-assigned this Aug 28, 2020
@JonathanMagnan
Copy link
Member

Hello @luizfbicalho ,

It's possible that new ( string(Id) as Id) as Tipo should be instead new ( string(Tipo.Id) as Id) as Tipo ?

var retorno = dados.AsQueryable()
				   .Select("new (  string(Id) as Id, string(Descricao) as Descricao,new (  string(Tipo.Id) as Id)  as Tipo, string(TipoId) as TipoId, string(Custo) as Custo)");

Once we change it, it now filters the Tipo.Id as you initially wanted.

Best Regards,

Jon


Performance Libraries
context.BulkInsert(list, options => options.BatchSize = 1000);
Entity Framework ExtensionsEntity Framework ClassicBulk OperationsDapper Plus

Runtime Evaluation
Eval.Execute("x + y", new {x = 1, y = 2}); // return 3
C# Eval FunctionSQL Eval Function

@luizfbicalho
Copy link
Author

Thanks @JonathanMagnan , I'll try that.

@luizfbicalho
Copy link
Author

One thing before closing this
If I remove the line

.Select("new ( string(Id) as Id, string(Descricao) as Descricao,new ( string(Id) as Id) as Tipo, string(TipoId) as TipoId, string(Custo) as Custo)");

Shoudn't it work inspecting the JObject?
I changed it to dynamic and received this

"Target object is not an ExpandoObject"

@JonathanMagnan
Copy link
Member

Unfortunately, the library is not 100% compatible with JObject.

So the answer is no for the moment.

We might want to improve the code later to try to support more but there is no plan for now.

@luizfbicalho
Copy link
Author

I didn't look deeply inside of the code, but is there some kind of translator that I could implement, for example
There is a object to where that translates the objects properties to the where string, and I could implement one translator of JObject to where,
and even one from dynamic to Where

I'm not sure if I was clear about it

@JonathanMagnan
Copy link
Member

I'm not exactly sure but this answer might help you: #410 (comment)

This is possible for you to add some method that will be recognized by the library

@luizfbicalho
Copy link
Author

I was thinking about something more transparent, I mean something like this

IReader{GetProperties(T obj).......}

and in Where("t=>t.Property==@0",X) would use the DI or some array of readers kind of the way newtonsoft.json has the converters.

I imagine that this is a huge change in the way that this works today, if so, I'm just pointing some ideas to help in the future

@StefH
Copy link
Collaborator

StefH commented Apr 8, 2024

I was more thinking in this direction:

Use it:

var array = JArray.Parse(@"[
        {
            ""first"": 1,
            ""City"": ""Paris"",
            ""third"": ""test""
        },
        {
            ""first"": 2,
            ""City"": ""New York"",
            ""third"": ""abc""
        }]");

        var results = array.Where("City == @0", "Paris").ToDynamicArray();
        foreach (var result in results)
        {
            Console.WriteLine(result.first);
        }

Logic

public static JArray Where(this JArray source, JsonParsingConfig config, string predicate, params object?[] args)
    {
        Check.NotNull(source);

        var array = new JArray();

        if (source.Count == 0)
        {
            return array;
        }

        // Convert the JArray to a dynamic object array / queryable.
        var enumerable = source.ToDynamicJsonClassArray(config.DynamicJsonClassOptions).AsQueryable();

        // Apply the where clause.
        var results = enumerable.Where(config, predicate, args);

        // Convert the dynamic results back to a JArray.
        foreach (var result in results)
        {
            array.Add(JObject.FromObject(result));
        }

        return array;
    }

@StefH StefH assigned StefH and unassigned JonathanMagnan Apr 13, 2024
@StefH StefH added the feature label Apr 13, 2024
@StefH
Copy link
Collaborator

StefH commented Apr 13, 2024

Will be solved by #789

@StefH StefH closed this as completed Apr 13, 2024
@StefH StefH added bug and removed feature labels Apr 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

3 participants