LinQ to SQL query constructed at runtime - c#

I have an xml file which contains query details like
<queries>
<query>
<name>GetStudentById</name>
<statement>select student_name from student where student_id=#id</statement>
</query>
</queries>
In C# code, the user will call a method ExecuteQuery(string queryname, hashtable params)
I will retrieve the query statement from the xml file using the query name.
The params hash table will contain values like
params['#id']=5
I will then use ADO .NET to construct the query and execute it at runtime using ExecuteReader after constructing the query statement and passing it the parameter list.
I want to know if it is possible to do it by using LinQ. Can someone show me how to execute the statement as a LinQ query?
Thanks,
David

Have a look at this SO post. Look at the answer from john skeet where he explains how to use the CSharpCodeProvider to execute the statement at runtime.
You will however have to convert your statement from sql to linq yourself. If there is no particular reason for it having to be linq, I would suggest keeping it in sql because at the end of the day you are going to parse sql to linq and then back to sql.
Even with dynamic linq you will have a problem because you will always have to specify the from class in your query.
Another option is that if you want to use this with your entity framework model, it would be way easier to use entity sql, have a look here and here for more info.

It's a considerable leap to go from using string query statements via ADO.NET to Linq to SQL. In the first instance you need to build your Linq to SQL entity model/DataContext. How you go about parsing a sql statement from text to Linq I'm not entirely sure, but if I wanted to look into how to achieve this I would be reading up on expression trees with a view to building a parser that takes your string query and referers to your entity model in order to produce a linq query.

Found something called LinqTextQueryBuilder at codeplex and another MS Library.
Links below
LinqTextQueryBuilder
http://msdn.microsoft.com/en-us/vstudio/bb894665.aspx

Related

LINQ to entities : cannot call a method

I'm aware there are alreay a lot of posts concerning this issue, but i can't seem to find a solution for this.
Here's my Ling to Entities query :
IEnumerable<Tblstamp> changes = (from c in userGSN.edb.Tblstamp
where (c.Ts_Date >= userGSN.DateLastCheck &&
TimeSpan.Parse(c.Ts_Time) >= userGSN.TimeLastCheck)
orderby c.Ts_Id ascending
select c);
I want to compare c.Ts_time to userGSN.TimeLastCheck, but for that I have to convert the c.Ts_Time to a timespan (it is a string, and comes from a database I can't modify, tried everything). I also can't do the converting before the query in an other variable since I can't access it outside of the query.
Obviously, I get an error for trying to use the TimeSpan.Parse method in my query, but I can't find any workaround to this. I have tried using LINQ to Object but since I am really not used to it I couldn't make the equivalent query that i have here.
I am aware of the problem, I'm just trying to find a workaround and need some help please !
EDIT :
So I tried the DateDiff function as suggested :
IEnumerable<Tblstamp> changes = (from c in userGSN.edb.Tblstamp
where (c.Ts_Date >= userGSN.DateLastCheck && SqlFunctions.DateDiff("second",userGSN.TimeLastCheck,c.Ts_Time).Value > 0 )
orderby c.Ts_Id ascending
select c
);
but it gives me the same error : "LINQ to Entities does not recognize the method 'System.Nullable1[System.Int32] DateDiff(System.String, System.Nullable1[System.TimeSpan], System.String)' method, and this method cannot be translated into a store expression."
Even though it clearly says here "You cannot call this function directly. This function can only appear within a LINQ to Entities query.", which is exactly what I'm doing ?!
There's no clean way to do this, so you'll have to think outside the box. Try using SqlFunctions.DateDiff to perform the check. You'll need to adapt it for your usage, but:
SqlFunctions.DateDiff("second", c.Ts_Time, userGSN.TimeLastCheck.ToString()) > 0
There are other methods that you can use, if DateDiff is not suitable. See EntityFunctions as well.
Depending on what you're using to query the data, you might want System.Data.Entity.SqlServer.SqlFunctions instead.
Every code you write in LinQ to get data from database must convert to a valid T-SQL query with valid statements. Not all C# methods have a correspondance in T-SQL so whenever you use them in your code while fatching data you will get errors.
You should either do modifications on the SQL side or use C# spesific functions after fething data from database, while working with entities in memory, or use fıunstions which comply with SQL statements.
If you can't get EF to translate your query to SQL, maybe you could do it yourself? See Writing SQL queries for entities
Linq to Entities does not support all functions since the query has to be translated to SQL:
from c in userGSN.edb.Tblstamp.AsEnumerable()
//now you are allready getting the data from the database
//so be carefull with that because you will have bad performance

What is difference between these 2 EF queries ? Which is best and why?

What is difference between these 2 queries in EF, which is best and why?
using (var context = new BloggingContext())
{
var blogs = (from b in context.Blogs select b).ToList();
var blogs = context.Blogs.ToList();
}
I believe your question is about Method Syntax vs Query Syntax. Your first query is based on Query Syntax and the second one is based on Method syntax.
See: Query Syntax and Method Syntax in LINQ (C#)
Most queries in the introductory Language Integrated Query (LINQ)
documentation are written by using the LINQ declarative query syntax.
However, the query syntax must be translated into method calls for the
.NET common language runtime (CLR) when the code is compiled.
EDIT:
With your edited code snippets, there is no difference between two queries at the time of execution. Your first query is based on query syntax which will compile into method syntax (your second query). To select between those two is a matter of choice. I personally finds method syntax more readable.
Old Answer:
However,There is a major difference between your two queries. Your first query is just a query construct, It hasn't been executed,considering that you have tagged Entity framework, Your first query will not bring any records from database in memory. To iterate the result set you need ToList(), ToArray() etc.
Your second query is infact getting all the records from your table and loading in a List<T> object in memory.
Also see: Deferred query execution
In a query that returns a sequence of values, the query variable
itself never holds the query results and only stores the query
commands. Execution of the query is deferred until the query variable
is iterated over in a foreach or For Each loop. This is known as
deferred execution; that is, query execution occurs some time after
the query is constructed. This means that you can execute a query as
frequently as you want to. This is useful when, for example, you have
a database that is being updated by other applications. In your
application, you can create a query to retrieve the latest information
and repeatedly execute the query, returning the updated information
every time.
Totally Agreed with #Habib right answer courtesy #Habib
Remember I copied from #Habib
I believe your question is about Method Syntax vs Query Syntax. Your first query is based on Query Syntax and the second one is based on Method syntax.
See: Query Syntax and Method Syntax in LINQ (C#)
Most queries in the introductory Language Integrated Query (LINQ) documentation are written by using the LINQ declarative query syntax. However, the query syntax must be translated into method calls for the .NET common language runtime (CLR) when the code is compiled.
EDIT: With your edited code snippets, there is no difference between two queries at the time of execution. Your first query is based on query syntax which will compile into method syntax (your second query). To select between those two is a matter of choice. I personally finds method syntax more readable.
First query doesn't perform anything, you are just constructing the query.
Second query fetches all the blog records from DB and load them into memory.
Which is best is depends on your needs.
Edit: If you are asking for syntax, there is no difference.The query syntax will be compiled into extension method calls by the compiler.
Apart from that, this:
from b in context.Blogs select b
is kinda pointless. It's equivelant to context.Blogs.Select(x => x). So in this case I would go with context.Blogs.ToList();

How to query DataTable and DataSet directly?

Is there's way to execute SQL queries directly on dataset or datatable . Query which need to be executed is much complex and it may be difficult to implement with Linq .
Is there any similar way to query directly from dataset or datatable ?
Is there any tools available to convert complex queries to linq ?
There is a DataTable.Select() method, which returns rows that match certain criteria.
The syntax is a little limited, however. Example:
DataTable.Select("Date > #1/1/2014# AND Name = \"John\"");
Should select any rows where the Date column has a date value that's 1/1/2014 or later, and the Name column is "John". Also handy is using String.Format() with it.
DataTable.Select(String.Format("Date > {0} AND Name = {1}", date, name));
This is severely limited compared to fixing it in the actual query, though.
try to use tools like LinqPad or some thing similiar
Download LinqPad
also one other way is to create your complex queries in database as VIEW and then write a simple select from VIEW!
another approach is, using MethodChain
What is the correct way to chain methods in .Net

lightswitch LINQ PreprocessQuery

I use the PreprocessQuery method to extend a query in lightswitch.
Something like this:
query = (from item in query
where (validIDs.Contains(item.tableIDs.myID)) &&
elementCount[item.ID] <= maxEleCount)
select item);
Where validIDs is a HashSet(int) and elementCount is a Dictionary(int, int).
the first where clause is working fine, but the second -> elementCount[item.ID] <= maxEleCount
is not working.
What i want to do is to filter a table by some IDs (validIDs) and check also if in another table the number of entries for every of this IDs does not exceed a limit.
Any ideas?
EDIT
I found a solution. Instead of a Dictionary I also used a HashSet for the second where clause. It seems it is not possible to do the Dictionary lookup inside the LINQ statement for some reason (?)
First, although being a bit pedantic, what you're doing in a PreProcessQuery method is "restricting" records in the query, not "extending" the query.
What you put in a LING query has to be able to be processed by the Entity Framework data provider (in the case of LS, the SQL Server Data Provider).
Sometimes you'll find that while your LINQ query compiles, it fails at runtime. This is because the data provider is unable to express it to the data store (again in this case SQL Server).
You're normally restricted to "primitive" values, so if you hadn't said that using a Dictionary actually worked, I would have said that it wouldn't.
Any time you have a static (as in non-changing) value, I'd suggest that you create a variable outside of your LINQ query, then use the variable in the LINQ query. By doing this, you're simply passing a value, the data provider doesn't have to try to figure out how to pass it to the data store.
Reading your code again, this might not be what you're doing, but hopefully this explanation will still be helpful.

Query Execution of SP while using it in LINQ to SQL

I have a query that returns a resultset. And I want to apply filter and sorting on the resultset.
Can someone help me understand if I use the query in LINQ (I'm using EF 4.0), will I be able to get deferred executuin so that when i apply filter/sort in entity model, the execution happens only one time (deffered)
Thanks in advance!
Regards,
Bhavik
If the query takes no parameters, then yes, as you could make a view that calls that sproc, expose the view in your model, then query it.
If it takes parameters, then if you need the sort/filter done server-side, then I think you'd have to add a wrapper sproc (or modify the existing one) to pass in the sort and filter to perform (basically, do it manually, but at least server-side).
Alternatively, you could write the sql to do it server side (sproc results into temp table, then select from that temp table and apply filtering, still manually) and then ExecuteStoreQuery
No, you can't defer the execution of a linq filtering to the stored proc in sql. The stored proc will be executed first, a resultset will be returned, you can then cast it to a list of your object types, once done that you can filter using Linq.
You can easily cast the resultset to a list of your objects using context.Translate<>
Have a look to these links :
enter link description here
List item
Of course the query (in your code) will not be evaluated until you cast it to a list, so you can concatenate all the filtering you want to your resultset and then call the ToList() to get the results.

Categories