T0Bi
November 11, 2020, 11:55am
1
Hello,
I was wondering if it is possible to dynamically create LINQ queries during runtime.
The idea is to let the user decide in which way to filter a datatable, without changing code in the bot.
Ideally I’d use an Excel file as config (or maybe a UiPath Form) which has the same format as the Filter Wizard from the Filter Data Table Activity
.
Example:
The user can then create the filter he likes and run the bot.
The bot will parse the config and create a LINQ query.
For this example the query would look like this:
(From row In dtTest.AsEnumerable Where row("Name").ToString.StartsWith("A") AndAlso Cint(row("Age").ToString) > 18 AndAlso row("Occupation").ToString.Contains("consultant") Select row).CopyToDataTable
As this always has a fixed format I think I can build this string with some basic string manipulation.
My big problem is: How to make this executable?
I will have a string variable with a valid LINQ query, but I have no idea how to actually execute this or use this in an assign activity.
It’s possible when using an SQL query with an SQL DB, but in my case I need this to work with datatables.
Do you have any ideas on how to solve this?
Cheers,
T0Bi
2 Likes
Hey @T0Bi ,
Yes, this is possible.
But a serious workaround is required
You can read the entire condition of the data table and then just dynamically append into the Linq Query (may be in assign)
Any more help let me know
Thanks
ppr
(Peter Preuss)
November 11, 2020, 4:56pm
3
@T0Bi
LINQ statement is a result of a compilation, so out of the box not ready for constructing on runtime.
There are some techniques to inject dynamics into the statement, but most of them are still derivable into its static base.
With the datatable.Select we do have more options do construct a search expression string.
Have a look here:
@Seetharaman_K
I defined a mapping table for constructing the search expression parts
[grafik]
Within a For each row over dtCriteria following LINQ generated the Search String respecting the dynamics
(From m In dtMap.AsEnumerable
Let val = row(m(0).toString).ToString
Where Not String.IsNullOrWhiteSpace(val)
Select para = m(1).toString.Trim.Replace("<par>", val )).toArray
iteration over dtMap
memorize the value of dtCriteria iteration row from Column with ColName as by current m(0) // Mappi…
for dynamic LINQs and what others had be done on this so far have a look here:
http://ak-dynamic-linq.azurewebsites.net/
https://docs.telerik.com/data-access/developers-guide/linq-support/data-access-feature-ref-linq-support-dynamic-linq
just to mention a few works
2 Likes
T0Bi
November 11, 2020, 5:49pm
4
@Nithinkrishna
what do you mean by
then just dynamically append into the Linq Query
?
@ppr
I already did this for datatable.Select, it was actually my first try to check if something like this might work.
The thing is, LINQ queries are up to 5 times faster than .select()
and I’m handling several datatables with 50k rows+. If I’d use select
instead of LINQ it would add hours to a single process.
I tried using this nuget package NuGet Gallery | NReco.LambdaParser 1.1.0
It basically enables one to parse strings into executable code. It works great, even in UiPath, but it cannot handle loops.
I’m still trying to use a combination of tools…
I’ll check out your links as well, thanks a lot!
The problem has boiled down to this single question: How to execute (arbitrary) code from strings in .NET?
Once I figure this out, everything else is easy.
ppr
(Peter Preuss)
November 11, 2020, 6:04pm
5
if i got you right so the questions goes into the direction like do we have an eval() like option etc. in .Net. As this falls into your idea / approach execute code provided on runtime as string
Same thing. cannot by pass the compiler. But explore by your self e.g. browsing forum / google.
You can have a look on Roslyn on what there is done or possible just to get some ideas.