My Blogs Collection
http://porwin-ebook.blogspot.com/search/label/Dot%20Net
the LIKE operator allows us to perform basic pattern-matching using wildcard characters. For Microsoft SQL Server, the wildcard characters are defined as follows:
| Wildcard | Description |
|---|---|
| _ (underscore) | matches any single character |
| % | matches a string of one or more characters |
| [ ] | matches any single character within the specified range (e.g. [a-f]) or set (e.g. [abcdef]). |
| [^] | matches any single character not within the specified range (e.g. [^a-f]) or set (e.g. [^abcdef]). |
A few examples should help clarify these rules.
Usually when writing a SQL statement you start out with ‘SELECT’ then define what data to select, then you have ‘FROM’ clause in which you define where to get the data, then, if you have a ‘JOIN’ you would define your join and what tables to join. After that you would define your ‘WHERE’ clause and specify how you want to filter this data so it would look something like this:
SELECT a.col1, a.col2, b.col1, b.col2
FROM table1 a
INNER JOIN table2 b ON a.ID = b.ID
WHERE a.col1 > 0
Not so with LINQ to SQL. Ultimately this would be the SQL code sent to the server but your LINQ code starts out with your ‘FROM’ clause, then you specify your ‘WHERE’ criteria, then you specify your ‘JOIN’ statement and last (but not least) you write your ‘SELECT’ statement so it looks more like this:
mydatacontext db = new mydatacontext(connectionstring);
var query = from p in db.table1
where p.col1 > 0
join i in db.table2 on p.ID equals i.ID
select new
{
p.col1,
p.col2,
i.col1,
i.col2
};
As you can see this is very similar in many was to ANSI SQL standard but in many ways it is quite different.
Our first example shows how to create a query and execute a join, but this is only an inner join. Many times you will need to do an outer join which allows you to to guarantee that you will get all the results from one table and nulls from the other set of joined data if there is no data to be joined. So the SQL equivalent is:
SELECT a.FirstName, a.LastName, b.Product
FROM Persons a
LEFT OUTER JOIN Products b ON a.PersonID = b.PersonID
WHERE a.LastName = 'Smith'
And the LINQ equivalent is:
var query = from a in db.Persons
join b in db.Products on a.PersonID equals b.PersonID into g
from b in g.DefaultIfEmpty()
where p.LastName == "Smith"
select new
{
a.FirstName,
a.LastName,
b.Product
};
What enables us to do this left outer join is the ‘DefaultIfEmpty()’ function which simply returns whatever the default value from the database is if there is no data.
A very handy tool in SQL is the ‘IN’ clause that allows you to select data based on multiple criteria without having to have a ton of ‘AND’ conjunctions and criteria. So basically you can specify the following:
SELECT * FROM TABLE WHERE col1 IN ('uno', 'dos', 'tres')
When specifying an IN clause in LINQ you would write the following:
string[] test = new string[] {"uno", "dos", "tres"};
mydatacontext db = new mydatacontext(connectionstring);
var query = from t in db.table
where test.Contains(t.col1)
select t;
Notice how you use the C# function ‘Contains’ and this is automatically translated into SQL ‘IN’ clause.
Subqueries are essential to any database developer. Many times you run into situations in which you must get data from one table and calculated data from another table into one object. For instance what if we have a driver’s table which included data on a particular driver such as their name/address and so on. Then we have another table which has raw data that includes their speed in cities, residential areas etc… If you wanted to get the average speed of a driver along with their bio information you could write the following SQL code:
SELECT td.DID, td.FirstName, td.LastName, td.Address,
(SELECT AVG(ts.speed) FROM tblSpeed ts WHERE ts.DID = td.DID AND ts.Location = 'residential') AS avgResidentialSpeed
FROM tblDrivers td
To produce something like this in LINQ you could write the following:
mydatacontext db = new mydatacontext(connectionstring);
var query = from d in db.tblDrivers
select new
{
d.FirstName,
d.LastName,
d.Address,
avgResidentialSpeed = (from s in tblSpeed
where s.DID == d.DID
&& s.Location == "residential").Avg()
};
As you can see you simply nest LINQ queries and the translation to SQL is a subquery.
One way SQL allows you to control flow is through CASE statements. This is translated by LINQ by using a ternary (shorthand) ‘if’ statement. For instance, to get the following SQL statement:
SELECT * FROM TABLE WHERE Col1 = CASE WHEN Col2 = 'A' THEN '1' WHEN Col2 = 'B' THEN '2' END
you would need to write the following LINQ code:
var Query = from p in db.Table
where Col1 == (Col2 == "A" ? "1" : Col2 == "B" ? "2")
select p;
This code translates into a case statement in SQL.
Sometimes you will want to get a single object from a table such as one customer object. To do this you can end your LINQ statement with the ‘FirstOrDefault’ function:
var customer = (from c in db.Customers
where c.CustomerID == 11356
select c).FirstOrDefault();
This will return one customer object from the Customers table and you have all the warm fuzzies such as intellisense. The FirstOrDefault() will return null if it does not find any data in the DB. If you need to ensure that you only receive one result you can use Single(), which will return an error if the DB finds more than one result, or if you need to return the first of several results but you want to return an error if there is none then you can use First() function.
Sometimes you may be working with a very complex query that takes a good amount of time to complete. Of course you will always want to ensure that your table structures are setup in an optimal way with indexes etc, but sometimes your app requirements are such that you end up with a very complex query in which case your code may timeout before it receives the response from the database. You can manually control the query timeout time of a LINQ object by going into your LINQ object and hard coding the following:
partial void OnCreated()
{
this.CommandTimeout = 3600;
}
The default is 300, so this will extend the time that your query can run.
When migrating your application to a production server you may get an error that says:
Compiler Error Message: CS0234: The type or namespace name 'Linq' does not exist in the namespace 'System.Data' (are you missing an assembly reference?)
The issue here is that your web.config file is not referencing the LINQ assembly. you can add in the reference to the assembly by adding in:
| Contents [hide] |
|---|
In this article, we’ll see the basic concepts of SQL JOINs. In the later part of the article, we’ll focus on the advanced subject of Self-JOIN and some interesting observations on how inner JOIN can be simulated using left JOIN. The author has tried his best to amalgamate various topics in a single concept.
The JOIN keyword is used in a SQL statement to query data from two or more tables based on a relationship between certain columns in these tables.
A JOIN that displays only rows that have a match in both the JOINed tables is known as inner JOIN. This is the default type of JOIN in the Query and View Designer.
A JOIN that includes rows even if they do not have related rows in the joined table is an Outer JOIN. You can create three different outer JOINs to specify the unmatched rows to be included:
Left Outer JOIN: In Left Outer JOIN, all rows in the first-named table, i.e. “left” table, which appears leftmost in the JOIN clause, are included. Unmatched rows in the right table do not appear.
Right Outer JOIN: In Right Outer JOIN, all rows in the second-named table, i.e. “right” table, which appears rightmost in the JOIN clause, are included. Unmatched rows in the left table are not included.
Full Outer JOIN: In Full Outer JOIN, all rows in all the joined tables are included, whether they are matched or not.
The following are three classic examples to demonstrate the cases where Outer JOIN is useful. You must have noticed several instances where developers write query as given below.
The query demonstrated above can be easily replaced by Outer JOIN. Indeed, replacing it by Outer JOIN is the best practice. The query that generates the same result as above is shown here using Outer JOIN and WHERE clause in JOIN.
The above example can also be created using Right Outer JOIN.

NOT Inner JOIN
Remember, the term Not Inner JOIN does not exist in database terminology. However, when full Outer JOIN is used along with WHERE condition, as explained in the above two examples, it will give you exclusive result to Inner JOIN. This JOIN will show all the results that were absent in Inner JOIN.

A cross JOIN devoid of a WHERE clause produces the Cartesian product of the tables involved in the JOIN. The size of a Cartesian product result set is the number of rows in the first table multiplied by the number of rows in the second table. One common example is when a company lists all its products in a pricing table to compare each product with others prices.

In this particular case, one table JOINs to itself with one or two aliases to stave off confusion. A self-JOIN can be of any type, as long as the joined tables are the same. A self-JOIN is unique in the sense that it involves a relationship with only one table. A common example is when a company has a hierarchal reporting structure whereby a member of staff reports to another member. Self-JOIN can either be an Outer JOIN or an Inner JOIN.
Self-JOIN is accomplished by using table name aliases to give each instance of the table a separate name. Joining a table to itself can be useful when you want to compare values in a column to other values of the same column. Self-JOIN is a JOIN in which records from a table are combined with other records from the same table when there are matching values in the joined fields. A self-JOIN can either be an inner JOIN or an outer JOIN. A table is joined to itself based upon a field or combination of fields that have duplicate data in different records. The data type of the inter-related columns must be of the same type or cast to the same type.
Now, think of a situation where all the data you require is contained within a single table, but data needed to extract is related to each other in the table itself. Examples of this type of data relate to employee information, where the table may have both an employee’s ID number for each record and also a field that displays the ID number of an employee’s supervisor or manager. To retrieve the data, it is mandatory for the tables to relate/JOIN to itself.
Another example that can be tried on SQL SERVER 2005 sample database AdventureWorks is to find products that are supplied by more than one vendor. Please refer to the sample database for table structure.
Before we continue further let me make it very clear that INNER JOIN should be used where it cannot be used and simulating INNER JOIN using any other JOINs will degrade the performance. If there are scopes to convert any OUTER JOIN to INNER JOIN, it should be done with priority.
Run the following two scripts and observe the result-set. It will be identical.
After gazing at the identical result the first question that cropped up in my mind was - what is behind the scene plan? Looking at the actual execution plan of the query it is quite evident that even if LEFT JOIN is used in SQL Server Query Optimizer, it converts to INNER JOIN since results are the same and performance is better.

Looking at the above scenario it makes me ponder how smart Query Optimizer Engine is and how it might be saving innumerable performance-related issues for sub-optimal queries.
Now let us try to grasp the cause of LEFT JOIN acting as INNER JOIN. When 1= 1 is used in ON clause it is always true and converts LEFT JOIN to CROSS JOIN. However, when WHERE condition’s effect is applied to the above CROSS JOIN it produces a result similar to INNER JOIN in our case. SQL Server Query Optimizer interprets this in advance and uses INNER JOIN right away.
I think a good question to ask in an interview would be -“How to write an OUTER JOIN that will give you the exact result, execution plan and performance as INNER JOIN?”
If there is any other explanation apart from what I have given or if you want to share a similar example