Embedding query strings into applications has long been a source of frustration and even led to a class of vulnerabilities known as "SQL Injection" where data passed from an untrusted source ends up being sent in its raw form to the database server where it can control query results or modify data.
Other limitations of these "string queries" can include incorrect formatting of data (e.g. dates which may be in a reverse format), the lack of strong-typing of the query itself, and reduced performance caused by parsing and cache misses.
Query expressions are designed to address many of these issues and are one of the two LINQ syntaxes available (the other uses methods with Lambda expressions C# 3.0) however this is the more SQL-like one.
Code
C#
var query = from p in db.Posts
select p.Id, p.Title, p.Content
where p.Id == postId;
foreach(var result in query) {
// Each result is a strongly-typed C# object
// Process them
}
C#
var query="SELECT Id, Title, Content FROM Posts WHERE Id=@PostId";
var cmd = connection.CreateCommand(query, connection);
cmd.Parameters.AddWithValue("@PostId", postId);
foreach(var row in cmd.ExecuteReader()) {
// Each row in the data reader contains columns of individual values
// Process them...
}
Notes
- Query expressions also support
join
,groupby
,orderby
etc. - LINQ is vendor-independent and query generation happens at runtime
- This means (in theory) LINQ Providers can be switched out for different databases (in reality the subtle differences between databases require testing and tweaking)
- Some providers still internally tweak the SQL generation based on the version number of the server at the other end
- These query expressions (sometimes called comprehension syntax) directly compile to LINQ method calls (sometimes called lambda syntax)
- The
let
keyword actually creates a new anonymous class to carry the value forward to the next operation