This topic gives a brief introduction to LINQ query expressions and some basic query to used to perform some action.
In few years the changing in technology and database, the user must want to performance of working is so fast ans also great challenge to retrieve data faster and not difficulty create in programming side.
It has become apparent that the next big challenge in programming technology is to reduce the complexity of accessing and integrating information that is not natively defined using OO technology. The two most common sources of non-OO information are relational databases and XML.
The major advantage of Microsoft’s LINQ Project is the general approach they have taken because they have integrated a query language irrespective of any specific part.Language Integrated Query can be used with XML,Database or anything which is capable of returning IENUMERABLE.
This is a snippet which i found in the doc itself which can express the power of LINQ and make programmers of dot net really smile.
A query is a set of instructions that describes what data to retrieve from a given data source (or sources) and what shape and organization the returned data should have. A query is distinct from the results that it produces.
Generally, the source data is organized logically as a sequence of elements of the same kind. A SQL database table contains a sequence of rows. Similarly, an ADO.NET DataTable contains a sequence of DataRow objects. In an XML file, there is a "sequence" of XML elements (although these are organized hierarchically in a tree structure). An in-memory collection contains a sequence of objects.
From an application's viewpoint, the specific type and structure of the original source data is not important. The application always sees the source data as an IEnumerable<(Of <(T>)>) or IQueryable<(Of <(T>)>) collection. In LINQ to XML, the source data is made visible as an IEnumerable< XElement>. In LINQ to DataSet, it is an IEnumerable< DataRow>. In LINQ to SQL, it is an IEnumerable or IQueryable of whatever custom objects you have defined to represent the data in the SQL table.
Given this source sequence, a query may do one of three things:
•Retrieve a subset of the elements to produce a new sequence without modifying the individual elements. The query may then sort or group the returned sequence in various ways, as shown in the following example (assume scores is an int[]):
Obtaining a Data Source
In a LINQ query, the first step is to specify the data source. In C# as in most programming languages a variable must be declared before it can be used. In a LINQ query, the from clause comes first in order to introduce the data source (Student) and the range variable (Stud).
The first thing is to import Data.Linq namespace.
Import namespace using System.Data.Linq;
Standard Query Operators
The set of query operators defined by LINQ are exposed to the user as the Standard Query Operator API. The query operators supported by the API are
Select / SelectMany
The Select statement performs a projection on the collection to select either all the data members that make up the object or a subset of it. The SelectMany operator performs a one-to-many projection("nested"), i.e., if the objects in the collection contain another collection as a data member, SelectMany can be used to select the entire sub-collection. The user supplies a function, as a delegate, which projects the data members. Selection creates an object of a different type, which has either some or as many data members as the original class. The class must be already defined for the code to be compilable.
Where
The Where operator allows the definition of a set of predicate rules which are evaluated for each object in the collection, while objects which do not match the rule are filtered away. The predicate is supplied to the operator as a delegate.
Sum / Min / Max / Average / Aggregate
These operators take a predicate that retrieves a certain numeric value from each element in the collection and uses it to find the sum, minimum, maximum, average or aggregate values of all the elements in the collection, respectively.
Join / GroupJoin
The Join operator performs an inner join on two collections, based on matching keys for objects in each collection. It takes two functions as delegates, one for each collection, that it executes on each object in the collection to extract the key from the object. It also takes another delegate via which the user specifies which data elements, from the two matched elements, should be used to create the resultant object. The GroupJoin operator performs a group join. Like the Select operator, the results of a join are instantiations of a different class, with all the data members of both the types of the source objects, or a subset of them.
Take / TakeWhile
The Take operator selects the first n objects from a collection, while the TakeWhile operator, which takes a predicate, selects those objects which match the predicate.
Skip / SkipWhile
The Skip and SkipWhile operators are complements of Take and TakeWhile - they skip the first n objects from a collection, or those objects which match a predicate (for the case of SkipWhile).
OfType
The OfType operator is used to select the elements of a certain type.
Concat
The Concat operator concatenates two collections.
OrderBy / ThenBy
The OrderBy operator is used to specify the primary sort ordering of the elements in a collection according to some key. The default ordering is in ascending order, to reverse the order, the OrderByDescending operator is to be used. ThenBy and ThenByDescending specifies subsequent ordering of the elements. The function to extract the key value from the object is specified by the user as a delegate.
Reverse
The Reverse operator reverses a collection.
GroupBy
The GroupBy operator takes a delegate that extracts a key value and returns a collection of IGrouping
Distinct
The Distinct operator removes duplicate instances of a key value from a collection. The function to retrieve the key value is to be supplied as a delegate.
Union / Intersect / Except
These operators are used to perform a union, intersection and difference operation on two sequences, respectively.
EqualAll
The EqualAll operator checks if all elements in two collections are equal.
First / FirstOrDefault / Last / LastOrDefault
These operators take a predicate. The First operator returns the first element for which the predicate yields true or throws an exception if nothing matches. The FirstOrDefault operator is like the First operator except that it returns the default value for the element type (usually a null reference) in case nothing matches the predicate. The last operator retrieves the last element to match the predicate, or throws an exception in case nothing matches. The LastOrDefault returns the default element value if nothing matches.
Single
The Single operator takes a predicate and returns the element which matches the predicate. An exception is thrown if none or more than one element match the predicate.
ElementAt
The ElementAt operator retrieves the element at a given index in the collection.
Any / All / Contains
The Any operator checks if there are any elements in the collection matching the predicate. It does not select the element, but returns true for a match. The All operator checks if all elements match the predicate. The Contains operator checks if the collection contains a given value.
Count
The Count operator counts the number of elements in the given collection.
The Standard Query Operator API also specifies certain operators that convert a collection into another type
•AsEnumerable: converts the collection to IEnumerable
•ToQueryable: converts the collection to IQueryable
•ToArray: converts the collection to an array.
•ToList: converts the collection to IList
•ToDictionary: converts the collection to IDictionary
•ToLookup: converts the collection to ILookup
•Cast: converts a non-generic IEnumerable collection to one of IEnumerable
•OfType: converts a non-generic IEnumerable collection to one of IEnumerable
The query operators are defined in the IEnumerable
Language Extensions
While LINQ is primarily implemented as a library for .NET Framework 3.5, it also defines a set of language extensions that can be optionally implemented by languages to make queries a first class language construct and provide syntactic sugar for writing queries. These language extensions have initially been implemented in C# 3.0, VB 9.0 and Oxygene, with other languages like F# and Nemerle having announced preliminary support. The language extensions include
Query syntax: A language is free to choose a query syntax that it will recognize natively. These language keywords must be translated by the compiler to appropriate LINQ method calls. The languages can implement operator reordering and other optimizations at the keyword level.
• Implicitly typed variables: This enhancement allows variables to be declared without specifying their types. The languages C# 3.0 and Oxygene declare them with the var keyword. In VB9.0, the use of the Dim keyword without type declaration accomplishes the same declaration. Such objects are still strongly typed; for these objects the compiler uses type inference to infer the type of the variables. This allows the result of the queries to be specified and their result defined without declaring the type of the intermediate variables.
• Anonymous types: Anonymous types allow classes, which contain only data member declarations, to be inferred by the compiler. This is useful for the Select and Join operators, whose result types may differ from the types of the original objects. The compiler uses type inference to determine the fields contained in the classes and generates accessors and mutators for these fields.
• Object Initializer: Object initializers allow an object to be created and initialized in a single scope, this allows creation of delegates that extract fields from an object, create a new object and assign the extracted data to the fields of the new object in a single statement, as is required for Select and Join operators.
• Lambda expressions: Lambda expressions are used to create delegates inline with other code. This allows the predicates and extraction functions to be written inline with the queries.
For example, in the query to select all the objects in a collection with SomeProperty less than 10,
int someValue = 5;
var results = from c in someCollection
let x = someValue * 2
where c.SomeProperty < x
select new {c.SomeProperty, c.OtherProperty};
foreach (var result in results)
{
Console.WriteLine(result);
}
the types of variables result, c and results all are inferred by the compiler - assuming SomeCollection is IEnumerable
IEnumerable
SomeCollection.Where
(
c => c.SomeProperty < (SomeValue * 2)
)
.Select
(
c => new {c.SomeProperty, c.OtherProperty}
)
foreach (SomeOtherClass result in results)
{
Console.WriteLine(result.ToString());
}
LINQ Providers
LINQ also defines another interface, IQueryable
LINQ to Objects
The LINQ to Objects provider is used for querying in-memory collections, using the local query execution engine of LINQ. The code generated by this provider refers to the implementation of the standard query operators as defined in the Sequence class and allows IEnumerable
LINQ to XML
The LINQ to XML provider converts an XML document to a collection of XElement objects, which are then queried against using the local execution engine that is provided as a part of the implementation of the standard query operator.
LINQ to SQL
The LINQ to SQL provider allows LINQ to be used to query SQL Server databases as well as SQL Server Compact databases. Since SQL Server data resides on a remote server, and because it already includes a querying engine, LINQ to SQL does not use the query engine of LINQ. Instead, it converts a LINQ query to a SQL query which is then sent to SQL Server for processing.[6] However, since SQL Server stores the data as relational data and LINQ works with data encapsulated in objects, the two representations must be mapped to one another. For this reason, LINQ to SQL also defines the mapping framework. The mapping is done by defining classes that correspond to the tables in the database, and containing all or a subset of the columns in the table as data members. The correspondence, along with other relational model attributes such as primary keys are specified using LINQ to SQL-defined attributes. For example,
LINQ to SQL
The LINQ to SQL provider allows LINQ to be used to query SQL Server databases as well as SQL Server Compact databases. Since SQL Server data resides on a remote server, and because it already includes a querying engine, LINQ to SQL does not use the query engine of LINQ. Instead, it converts a LINQ query to a SQL query which is then sent to SQL Server for processing. However, since SQL Server stores the data as relational data and LINQ works with data encapsulated in objects, the two representations must be mapped to one another. For this reason, LINQ to SQL also defines the mapping framework. The mapping is done by defining classes that correspond to the tables in the database, and containing all or a subset of the columns in the table as data members. The correspondence, along with other relational model attributes such as primary keys are specified using LINQ to SQL-defined attributes. For example,
[Table(Name="Customers")
public class Customer
{
[Column(IsPrimaryKey = true)]
public int CustID;
[Column]
public string CustName;
}
this class definition maps to a table named Customers and the two data members correspond to two columns. The classes must be defined before LINQ to SQL can be used. Visual Studio 2008 includes a mapping designer which can be used to create the mapping between the data schemas in the object as well as the relational domain. It can automatically create the corresponding classes from a database schema, as well as allow manual editing to create a different view by using only a subset of the tables or columns in a table.
The mapping is implemented by the DataContext which takes a connection string to the server, and can be used to generate a Table
LINQ to DataSets
The LINQ to SQL provider works only with Microsoft SQL Server databases; to support any generic database, LINQ also includes the LINQ to DataSets, which uses ADO.NET to handle the communication with the database. Once the data is in ADO.NET Datasets, LINQ to Datasets execute queries against these datasets.
Other providers
The LINQ providers can be implemented by third parties for various data sources as well. Several database server specific providers are available from the database vendors. Some of the popular providers include:
HOW LINQ WORKS WITH XML:
The extensibility of the query architecture is used in the LINQ project itself to provide implementations that work over both XML and SQL data.
Xpath and Xquery which is used heavily is in the host programming language.
XmlDocument doc = new XmlDocument();
XmlElement name = doc.CreateElement(”name”);
name.InnerText = “Patrick Hines”;
XmlElement phone1 = doc.CreateElement(”phone”);
phone1.SetAttribute(”type”, “home”);
XmlElement phone2 = doc.CreateElement(”phone”);
phone2.SetAttribute(”type”, “work”);
XmlElement street1 = doc.CreateElement(”street1″);
XmlElement city = doc.CreateElement(”city”);
city.InnerText = “Mercer Island”;
XmlElement state = doc.CreateElement(”state”);
state.InnerText = “WA”;
XmlElement postal = doc.CreateElement(”postal”);
postal.InnerText = “68042″;
XmlElement address = doc.CreateElement(”address”);
address.AppendChild(street1);
address.AppendChild(city);
address.AppendChild(state);
address.AppendChild(postal);
XmlElement contact = doc.CreateElement(”contact”);
contact.AppendChild(name);
contact.AppendChild(phone1);
contact.AppendChild(phone2);
contact.AppendChild(address);
XmlElement contacts = doc.CreateElement(”contacts”);
contacts.AppendChild(contact);
doc.AppendChild(contacts);
If we see it little closer the above code , This style of coding provides few clues to the structure of the XML tree. but with LINQX it becomes more of what they as functional construct. Here is what how u code the same with LINQX
XElement contacts = new XElement
(”contacts”,new XElement(”contact”,
new XElement(”name”, “Patrick Hines”),
new XElement(”phone”, “206-555-0144″,
new XAttribute(”type”, “home”))
,new XElement(”phone”, “425-555-0145″,new XAttribute(”type”, “work”)),
new XElement(”address”,new XElement(”street1″, “123 Main t”),
new XElement(”city”, “Mercer Island”),
new XElement(”state”, “WA”),new XElement(”postal”,”6843″)
How LINQ works with database
The query operators over relational data (DLinq) build on the integration of SQL-based schema definitions into the CLR type system.
This integration provides strong typing over relational data while retaining the expressive power of the relational model and the performance of query evaluation directly in the underlying store.
What we need to know is the structure of database table we want to deal with it and create a class exactly having private variables as columns of the underlying table say may be like save that easy. Thus in simple ways we create an object of the row of that table in memory and do operation on that and ask somebody to save it. Moreover we can ask for a collection of those rows of get more than one record and do a query on it.Isn’t that great no hassles of database sql.
Create an entity class with mapping to database table like this:-
Table(Name="Students")]
public class Student
{
[Column (Id=true)]
public string StudentID;
private string _City;
[Column(Storage = "_City")]
public string City
{
get { return this._City; }
set { this._City = value; }}}
Create a Data context to load from database
static void Main(string[] args){
// Use a standard connection string
DataContext db = new DataContext(@”C:StudentRegistration.mdf”);
// Get a typed table to run queries
Table Students = db.GetTable();
Query what you get
// This is only for debugging / understanding the working of DLinq
db.Log = Console.Out;
// Query for customers in London
var Stud =
from c in Students
where c.City == “Karachi”
select c;
}
Example:
class LINQQueryExpressions
{
static void Main()
{
int[] scores = new int[] { 97, 92, 81, 60 };
IEnumerable
from score in scores
where score > 80
select score;
foreach (int i in scoreQuery)
{
Console.Write(i + " ");
}
}
}
// Output: 97 92 81
Example:
IEnumerable
from score in scores
where score > 80
orderby score descending
select String.Format("The score is {0}", score);
Retrieve a singleton value about the source data, such as:
• The number of elements that match a certain condition.
• The element that has the greatest or least value.
• The first element that matches a condition, or the sum of particular values in a specified set of elements. For example, the following query returns the number of scores greater than 80 from the scores integer array:
int highScoreCount =
(from score in scores
where score > 80
select score)
.Count();
the use of parentheses around the query expression before the call to the Count method. You can also express this by using a new variable to store the concrete result. This technique is more readable because it keeps the variable that store the query separate from the query that stores a result.
Enumerable
from score in scores
where score > 80
select score;
int scoreCount = highScoresQuery3.Count();
In the previous example, the query is executed in the call to Count, because Count must iterate over the results in order to determine the number of elements returned by highScoresQuery.
Write LINQ Queries in C#
This topic shows the three ways in which you can write a LINQ query in C#:
1. Use query syntax.
2. Use method syntax.
3. Use a combination of query syntax and method syntax.
Query Syntax
The recommended way to write most queries is to use query syntax to create query expressions. The following example shows three query expressions. The first query expression demonstrates how to filter or restrict results by applying conditions with a where clause. It returns all elements in the source sequence whose values are greater than 7 or less than 3. The second expression demonstrates how to order the returned results. The third expression demonstrates how to group results according to a key. This query returns two groups based on the first letter of the word.
/ Query #1.
List
// The query variable can also be implicitly typed by using var
IEnumerable
from num in numbers
where num < 3 || num > 7
select num;
// Query #2.
IEnumerable
from num in numbers
where num < 3 || num > 7
orderby num ascending
select num;
// Query #3.
string[] groupingQuery = { "carrots", "cabbage", "broccoli", "beans", "barley" };
IEnumerable
from item in groupingQuery
group item by item[0];
Note that the type of the queries is IEnumerable<(Of <(T>)>) . All of these queries could be written using var as shown in the following example:
var query = from num in numbers...
Method Syntax
Some query operations must be expressed as a method call. The most common such methods are those that return singleton numeric values, such as Sum, Max, Min, Average, and so on. These methods must always be called last in any query because they represent only a single value and cannot serve as the source for an additional query operation. The following example shows a method call in a query expression:
List
List
// Query #4.
double average = numbers1.Average();
// Query #5.
IEnumerable
If the method has parameters, these are provided in the form of a lambda expression, as shown in the following example:
// Query #6.
IEnumerable
In the previous queries, only Query #4 executes immediately. This is because it returns a single value, and not a generic IEnumerable<(Of <(T>)>) collection. The method itself has to use foreach in order to compute its value.
Each of the previous queries can be written by using implicit typing with var, as shown in the following example:
/ var is used for convenience in these queries
var average = numbers1.Average();
var concatenationQuery = numbers1.Concat(numbers2);
var largeNumbersQuery = numbers2.Where(c => c > 15);
Mixed Query and Method Syntax
This example shows how to use method syntax on the results of a query clause. Just enclose the query expression in parentheses, and then apply the dot operator and call the method. In the following example, query #7 returns a count of the numbers whose value is between 3 and 7. In general, however, it is better to use a second variable to store the result of the method call. In this manner, the query is less likely to be confused with the results of the query.
// Query #7.
// Using a query expression with method syntax
int numCount1 =
(from num in numbers1
where num < 3 || num > 7
select num).Count();
// Better: Create a new variable to store
// the method call result
IEnumerable
from num in numbers1
where num < 3 || num > 7
select num;
int numCount2 = numbersQuery.Count();
Because Query #7 returns a single value and not a collection, the query executes immediately.
The previous query can be written by using implicit typing with var, as follows:
var numCount = (from num in numbers.
It can be written in method syntax as follows:
var numCount = numbers.Where(n => n < 3 || n > 7).Count();
It can be written by using explicit typing, as follows:
int numCount = numbers.Where(n => n < 3 || n > 7).Count();
Example
Query a Collection of Objects
public class StudentClass
{
#region data
protected enum GradeLevel { FirstYear = 1, SecondYear, ThirdYear, FourthYear };
protected class Student
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int ID { get; set; }
public GradeLevel Year;
public List
}
protected static List
{
new Student {FirstName = "Terry", LastName = "Adams", ID = 120, Year = GradeLevel.SecondYear, ExamScores = new List
new Student {FirstName = "Fadi", LastName = "Fakhouri", ID = 116, Year = GradeLevel.ThirdYear,ExamScores = new List
new Student {FirstName = "Hanying", LastName = "Feng", ID = 117, Year = GradeLevel.FirstYear, ExamScores = new List
new Student {FirstName = "Cesar", LastName = "Garcia", ID = 114, Year = GradeLevel.FourthYear,ExamScores = new List
new Student {FirstName = "Debra", LastName = "Garcia", ID = 115, Year = GradeLevel.ThirdYear, ExamScores = new List
new Student {FirstName = "Hugo", LastName = "Garcia", ID = 118, Year = GradeLevel.SecondYear, ExamScores = new List
new Student {FirstName = "Sven", LastName = "Mortensen", ID = 113, Year = GradeLevel.FirstYear, ExamScores = new List
new Student {FirstName = "Claire", LastName = "O'Donnell", ID = 112, Year = GradeLevel.FourthYear, ExamScores = new List
new Student {FirstName = "Svetlana", LastName = "Omelchenko", ID = 111, Year = GradeLevel.SecondYear, ExamScores = new List
new Student {FirstName = "Lance", LastName = "Tucker", ID = 119, Year = GradeLevel.ThirdYear, ExamScores = new List
new Student {FirstName = "Michael", LastName = "Tucker", ID = 122, Year = GradeLevel.FirstYear, ExamScores = new List
new Student {FirstName = "Eugene", LastName = "Zabokritski", ID = 121, Year = GradeLevel.FourthYear, ExamScores = new List
};
#endregion
//Helper method
protected static int GetPercentile(Student s)
{
double avg = s.ExamScores.Average();
return avg > 0 ? (int)avg / 10 : 0;
}
public void QueryHighScores(int exam, int score)
{
var highScores = from student in students
where student.ExamScores[exam] > score
select new {Name = student.FirstName, Score = student.ExamScores[exam]};
foreach (var item in highScores)
{
Console.WriteLine("{0,-15}{1}", item.Name, item.Score);
}
}
}
public class Program
{
public static void Main()
{
StudentClass sc = new StudentClass();
sc.QueryHighScores(1, 90);
// Keep the console window open in debug mode
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
}
Eample:
Return a Query from a Method
class MQ
{
IEnumerable
{
var intsToStrings = from i in ints
where i > 4
select i.ToString();
return intsToStrings;
}
static void Main()
{
MQ app = new MQ();
int[] nums = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var myQuery = app.QueryMethod1(ref nums);
//execute myQuery
foreach (string s in myQuery)
{
Console.WriteLine(s);
}
//modify myQuery
myQuery = (from str in myQuery
orderby str descending
select str).
Take(3);
// Executing myQuery after more
// composition
Console.WriteLine("After modification:");
foreach (string s in myQuery)
{
Console.WriteLine(s);
}
// Keep console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
By
Usama Wahab Khan and Atif Shahzad
LINQ QUERY
Thursday, July 30, 2009
Posted by Usama Wahab Khan at 9:07 PM
Subscribe to:
Post Comments (Atom)
1 comments:
Good Article!!
Really helpfull Usama one thing I wanna know how much you have worked on SilverLight. I need some help regarding SL
Post a Comment