How to build a LINQ query from text at runtime? - c#

I have a
class A {
public int X;
public double Y;
public string Z;
// and more fields/properties ...
};
and a List<A> data and can build a linq query like e.g.
var q = from a in data where a.X > 20 select new {a.Y, a.Z};
Then dataGridView1.DataSource = q.ToList(); displays the selection in my DataGridView.
Now the question, is it possible to build the query from a text the user has entered at runtime? Like
var q = QueryFromText("from a in data where a.X > 20 select new {a.Y, a.Z}");
The point being, that the user (having programming skills) can dynamically and freely select the displayed data.

Dynamic Linq baby!
r.e. comment.
Yes, the example as written may not be possible using Dynamic Linq, but if you factor out the constants, e.g. 'from a in data' you are left with a 'where' and a 'select' which can be expressed with dynamic linq.
so two text boxes, maybe three if you include an orderby, could possibly satisfy your requirements.
Just a thought.
Jon has an interesting approach but i would be leery of compiling and executing unrestrained code.

Well, you can use CSharpCodeProvider to compile code at execution time. Have a look at Snippy for an example of this. In this case you'd need to compile the user code in a method which accepts a List<A> called data. My experience is that it works, but it can be slightly fiddly to get right - particularly in terms of adding the appropriate references etc.

Answering it pretty late; though, it will help someone who visits this page.
I had similar requirement and I solved it by dynamically compiling string as LINQ query, executing it over in-memory collection and collecting the result. Only catch is user input needs to be valid C# compile-able code else it returns an exception message instead of result.
Code is pretty long so here is the github link
Sample application on github shows multiple examples including projection.

Although there may be some ways to do this, LINQ simply isn't designed for this scenario. Using CodeDOM (as Jon suggested) is probably the only way to get that easily done. If you trust the user and he/she has programming skills, you could perhaps just use old fashioned methods and let the user enter the query using SQL?
If you, on the other hand, choose to create some visual tool for constructing queries, you don't need to build them by composing strings and you can compose expression trees instead. For example using Linq Kit and AsExpandable.

check out this library
http://msdn.microsoft.com/en-us/vcsharp/bb894665.aspx

Related

sorting, filtering, and paging with entity framework core 2

I'm creating a tabular grid of data and will have every column header sortable (both ascending and descending) as well as filterable by a textbox underneath the column name.
I've done some digging to find out the best approach to generating my LINQ queries for entity framework and best I found was this: https://learn.microsoft.com/en-us/aspnet/core/data/ef-mvc/sort-filter-page?view=aspnetcore-3.0
That just uses a big switch / case (for ordering only...doesn't even consider multiple filtering options beyond one). Surely there's got to be a better, more concise approach than this?
I'm half tempted to just use my old sproc and call the sproc with EF if this is really the path I'll have to go down.
Ideally, I'd want something like this:
return myContext.Where(x =>
x.%thisisadynamicfield%.Contains("%somefiltervalue%" &&
x.%anotherdynamicfield%.Contains("%someothervalue%" && ...)
.OrderBy(x => x.%someorderybydynamicfield%)
I'm ok using a conditional to determine ordering ascending or descending, but I'd really like to compact everything else as much as possible and that MS article I linked above looks like code vomit and it would only cover part of my needs.
EDIT: as is almost always the case, as soon as I post here and try one more searching effort, I find what I'm looking for. I just found this: https://github.com/harshwPro/EntityFrameworkPaginate which looks very promising. I will report back here if that solves my issue.
EDIT 2: well the github project I referenced in my first edit is certainly a cleaner solution than the MS article I posted originally but it still leaves me with writing a huge conditional to generate my filters by property. Using that solution, I'd have to write something like this:
dataPagingModel.Filters.Add(true, x => x.MyCoolProperty.Contains("blah")); but would have to conditionally add new filters based on my angular presentation layer's posted parameters - switch / case, or some huge if / else block. What I'd ideally like is a way to just loop over all of the posted filters list and dynamically add those filters in a loop. So I guess my question now boils down to, is there a way to access properties of an object dynamically (generically) in a lambda expression?
EDIT 3: I think this SO post has the answers I need: Generic method to filter a list object

When/why would you use Linq in an application? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
i know how linq works but i am not getting idea where exactly i should use linq?
The question is rather like asking "I know how plus and minus work, but when do I use addition? When do I use subtraction?"
You use addition when you want to know the sum of two things and subtraction when you want to know their difference.
Essentially all LINQ does is add operators to the C# and VB languages for sorting, filtering, projecting, joining and grouping. When do you use LINQ? When you want to sort, filter, project, join or group something.
I say use LINQ.. Absolutely anywhere that it will help accomplish your goal in a concise and maintainable way.
There is no broad use or don't use restrictions, you really have to make a judgement for the piece of code at hand to whether or not it will benefit from LINQ, in general some of the old overly verbose pieces of code (nested looping etc) can be more clearly expressed in LINQ and might be beneficial.
And it should be noted that LINQ is NOT synonymous with LINQ to SQL, LINQ stands for Language Integrated Query and is extraordinarily useful outside a database context.
LINQ is used generally when you have to work with IEnumerable (or IQueryable in case of operations against a database). It makes your code cleaner and more functional.
You could use it for example to replace a for loop:
from i in Enumerable.Range(0, n)
where i % 2 == 0
select i;
instead of:
for (int i = 0; i < n; i++)
{
if (i % 2 == 0)
{
something.Add(i);
}
}
You should use LINQ where you find it appropriate -because it can be both more expressive/concise than conventional common procedural programming idioms.
You can utilize it for a number of scenarios, e.g:
Retrieving data from Entity Framework or using Linq to SQL
Perform operations on collections (sorting, selecting, etc)
Traversing XML documents
These operations all require significantly less code using Linq.
LINQ is a standard. Custom layers you make are not, not unless your team pre-built and agreed upon a custom layer. If your team won't make custom layers, then using LINQ might alleviate the problem of each people having their own way of making requests to the database.
Anytime you want to filter data within your application without having to run a query. Here's a good place to look at examples of how you may want to use it.
http://msdn.microsoft.com/en-us/vcsharp/aa336746.aspx
For me it makes my code more concise and easier to maintain. use it anywhere you have to work with accessing or manipulting Collection of data like Databases, XML, Lists, etc.
But just keep in mind some of it quirks.
At places where it makes code more readable and maintainable.
In places where you work with collections of data and you want to transform, filter, connect or sort it.
You do not have to use LINQ, it is not the cure for all problems. It may actually perform worse than the procedual programmed way in some cases.
Start using it and with the time and experience you get the feeling where it makes sense and is most useful.
thanks for answer.
the answer might take pages why linq? but in short after reading ceratin books,
if i say The main goal of LINQ and LINQ to SQL is to
get rid of, or at least reduce An impedance mismatch between Relational database structure and object oriented . it’s easier to adapt the C# language than to change SQL or XML.
With LINQ, the aim is toward deeply integrating the capabilities of data query and
manipulation languages into programming languages.
LINQ removes many of the barriers among objects, databases, and XML. It
enables us to work with each of these paradigms using the same language-integrated
facilities.
i got answer from book *Linq In Action. *
in this first chapter clears why linq.
this is really good book.
Let's take an example. You want to write a simple query that retrieves customers as follows:
SELECT UPPER(Name)
FROM Customer
WHERE Name LIKE 'A%'
ORDER BY Name
That doesn't look too bad, right? But now suppose these results are feeding a web page, and we want to retrieve just rows 21-30. Suddenly, you need a subquery:
SELECT UPPER(Name) FROM
(
SELECT *, RN = row_number()
OVER (ORDER BY Name)
FROM Customer
WHERE Name LIKE 'A%'
) A
WHERE RN BETWEEN 21 AND 30
ORDER BY Name
Here's same query in LINQ. The gain in simplicity is clear:
var query =
from c in db.Customers
where c.Name.StartsWith ("A")
orderby c.Name
select c.Name.ToUpper();
var thirdPage = query.Skip(20).Take(10);
Only when we enumerate thirdPage will the query actually execute. In the case of LINQ to SQL or Entity Framework, the translation engine will convert the query (that we composed in two steps) into a single SQL statement optimized for the database server to which it's connected.

How to create LINQ Query from string?

I am new at LINQ and really need a help with some coding.
At the moment, I have a string and a var variables.
string temp = "from product in myEntities.Products where product.Name.Contains(_Name) select product";
var _Products = temp;
LvProducts.DataSource = _Products;
LvProducts.DataBind();
Basically, what I want to do is to be able to create a custom/complicated LINQ query by assigning it into a string beforehand. After done with composing, I assign the string into the var variable. However, this is obviously will not work. Therefore, can anyone assist me on this?
You have a few options:
Use the the Dynamic Linq
libraries to construct you queries on
the fly. The best place to get
started is by reading ScottGu's blog
entry. However, I don't think
these libraries support the contains
method in your example. Here is
a blog post explaining how to add
this support.
Directly execute SQL statements. Check out the MSDN docs for Linq to Sql or Linq to Entities.
var _Products = myEntities.ExecuteStoreQuery<Product>
(#"SELECT * FROM Products WHERE [Name] In ('Item1', 'Item2')");
Use Linq's composable behaviour. This might not be the most elegant solution but it works really well if you do not have too many options. You can just construct your query in multiple parts.
var _Products = from product in myEntities.Products
select product
_Products = from product in _Products
where product.Name.Contains(_Name)
select product
if FilterByPrice {
_Products = from product in _Products
where product.Price > 100
select product
}
You can do this by compiling this Linq within some c# using the CodeDomProvider - Adding scripting functionality to .NET applications - but this is quite heavyweight as a solution. If you want to see more about how to do this, then take a look at LinqPad - http://www.linqpad.net - the author invites you to use the decompiler to see how it works!
If the requirement is just down to simple where clauses than an alternative might be to use Dynamic Linq - see Scott Gu's posts and the sample code from Microsoft - http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
Maybe this can help you
http://nlinq.codeplex.com/
BR.
Much of the reason you use LINQ in the first place is to get compiler-verified queries, that wil ldetect errors at compile time. This will defeat that purpose since the string will be parsed at runtime.
For your needs you have two options:
1) Making a eSQL query and running it on the ObjectContext. Using this, you can still use your entities like myEntities.Products, and return a list of products.
2) Using a normal SQL query, and use the ObjectContext to call that directly towards the underlying database.
My guess is that you will have to use dynamic code execution. For further details, have a look at Ricks post on west-wind.
you're thinking of it like a Dynamic SQL where you create the statement as string and parse it as a SQL statement.
Since you're already in the code, why not make the statements right in there. It would be a lot easier if you use Lambda instead of the traditional linq. my 2 cents.

Dynamically adding select fields using LINQ lambda

Lets say we have an expression:
var prices = from p in PriceDB.Prices
where p.TypeID == 12
orderby p.PriceType.Title
select p;
Is it possible to modify the select list?
I imagine it looking something like this:
var newPriceList = prices.Select( p => p.ExchangeRate );
This may be an odd request, but in my code (which is too long and complex to post here) I want to conditionally add fields to be output depending on a CheckBoxList.
I assume, of course, that I'm trying to go about this the wrong way...
I imagine it looking something like this:
Actually it would look exactly like that. First, build a query, selecting the entire record. Then add a select (using the Select() method seem the easiest way) to limit the selection. Linq-to-Sql will sort out the two selects, and use the proper reselt, so theres just one select in the final SQL.
There's no really good way to choose between multiple selects. I would probably use a switch/case.
While you could go down the dynamic route, I would strongly consider not doing so. What is the cost of fetching the extra values if you don't need them, in your particular case? Is the problem that they're being displayed dynamically and you only want them displayed in certain cases? If so, I'd suggest modifying the display code somehow.
It's hard to stay strongly typed (which has various advantages) while being dynamic in terms of what you fetch. Of course, if you always want to fetch the same "shape" of data (e.g. always just a decimal value from each row) then that's reasonably easy - let me know if that's something you'd like to see demonstrated.
If you could tell us more about your problem, we may be able to suggest alternative solutions.
If I understood you correct this is explaining how to build dynamic queries:
http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
You might want to look at this Dynamic LINQ and Dynamic Lambda expressions?
Or the Dynamic Expression API (System.Linq.Dynamic).

Linq2Sql - Storing Complex Linq Queries for future dynamic execuction - raw text - possible?

I am having a lot of fun with Linq2Sql. Expression Trees have been great, and just the standard Linq2Sql syntax has been a lot of fun.
I am now down to part of my application where I have to somehow store queries in a database, that are custom for different customers that use the same database and same tables (well, view, but you know what I mean). Basically, I cant hard-code anything, and I have to leave the query language clear text so someone can write a new where-clause type query.
So, if that description was harsh, let me clarify:
In a previous version of our application, we used to do direct SQL calls to the db using raw SQL. Yea. it was fun, dirty, and it worked. We would have a database table fulled of different criteria like
(EventType = 6 and Total > 0)
or a subquery style
(EventType = 7
AND Exists (
select *
from events as e1
where events.EventType = e1.EventType
and e1.objectNumber = 89)
)
(sql injection anyone?)
In Linq2Sql, this is a little more challenging. I can make all these queries no problem in the CLR, but being able to pass dynamic where criterias to Linq is a little more challenging, especially if I want to perform a sub query (like the above example).
Some ideas I had:
Get the raw expression, and store it --- but I have no idea how to take the raw text expression and reverse it back to executable to object expression.
Write a SQl like language, and have it parse the code and generate Linq Expression -- wow, that could be a lot of fun
I am quite sure there is no SomeIqueryable.Where("EventType = 6 and Total > 54"). I was reading that it was available in beta1, but I don't see how you can do that now.
var exp2 = context.POSDataEventView.Where("EmployeeNumber == #0", 8310);
This would be the easiest way for me to deploy.. I think.
Store serialized Expressions -- wow.. that would be confusing to a user trying to write a query --- hell, I'm not sure I could even type it all out.
So, I am looking for some ideas on how I can store a query in some kind of clear text, and then execute it against my Linq2Sql objects in some fashion without calling the ExecuteSQL. I want to use the LinqObjects.
P.S. I am using pLinqo for this application if that helps. Its still linq2sql though.
Thanks in advance!
Perhaps the Dynamic LINQ Library (in the MSDN samples) would help?
In particular, usage like:
This should work with any IQueryable<T> source - including LINQ-to-Objects simply by calling .AsQueryable() on the sequence (typically IEnumerable<T>).

Categories