LINQ - Language Integrated Query Unifikacja dostępu do danych Uproszczone odpytywanie obiektów, daych i XML poprzez integrację zapytań z językiem programownia Umożliwia odpytywanie kolekcji implementujących IEnumerable<>, przykładowo tablicy, listy, XML DOM, tabel dazy danych Wprowadza zbliżoną do SQL składnię niezależną od źródła danych Oferuje sprawdzanie typów oraz dynamiczne tworzenie zapytań. LINQ namespaces: System.Core.dll System.Linq - operatory, System.Linq.Expressions System.Data.Linq.dll System.Data.Linq - LINQ to SQL, System.Data.Linq.Mapping, System.Data.Linq.SqlClient System.Data.DataSetExtensions.dll System.Data - LINQ to DataSet System.Xml.Linq.dll System.Xml.Linq - LINQ to XML
LINQ-enabled data sources Architektura LINQ LINQ To Objects LINQ-enabled ADO.NET Visual BasicOthers.Net Language Integrated Query (LINQ) Visual C# Objects XMLXML Databases LINQ To Datasets LINQ To Entities LINQ To XML LINQ To SQL
LINQ Data Providers Zewnętrzne: LINQ to Amazon LINQ to NHibernate LINQ to Active Directory LINQ to Google LINQ to MySQL LINQ to Excel LINQ to Sharepoint LINQ to JavaScript LINQ to CRM LINQ to Geo LINQExtender DBLINQ Linq provider for MySQL, Oracle, SQL Server, PostgreSQL, SQLite, Ingres and Firebird Microsoft: LINQ to Objects LINQ to SQL LINQ to XML LINQ to DataSet LINQ to Entities (EntityFramework) ParallelLINQ
ADO a relacyjne dane Błędy: Błąd składniowy w SQL – FROMM Niepoprawna nazwa parametru (o vs. 0) Polecenie nie połączone z połączeniem Połącznie nie otworzone Połączenie nie zamknięte Elementy nie dodane do listy wynikowej Pobieramy większą liczbę niż zwraca select List customers = new List (); SqlConnection c = new SqlConnection(ConnectionString); SqlCommand cmd = new c.Name, c.Phone, c.ID FROMM Customers c WHERE c.City "USA"); DbDataReader dr = cmd.ExecuteReader(); while (dr.Read()) { Customer cust = new Customer(); cust.CompanyName = dr.GetString(0); cust.ContactName = dr.GetString(1); cust.Country = dr.GetString(2); cust.CustomerID = dr.GetString(3); } dr.Close(); return customers; List customers = new List (); SqlConnection c = new SqlConnection(ConnectionString); SqlCommand cmd = new c.Name, c.Phone, c.ID FROMM Customers c WHERE c.City "USA"); DbDataReader dr = cmd.ExecuteReader(); while (dr.Read()) { Customer cust = new Customer(); cust.CompanyName = dr.GetString(0); cust.ContactName = dr.GetString(1); cust.Country = dr.GetString(2); cust.CustomerID = dr.GetString(3); } dr.Close(); return customers;
LINQ – składowe zapytania Każde zapytanie składa się z 3 niezależnych akcji: 1.Pobranie źródła danych. 2.Stworzenie zapytania. 3.Wykonanie zapytania. class IntroToLINQ { static void Main() { // The Three Parts of a LINQ Query: // 1. Data source. int[] numbers = new int[5] { 0, 1, 2, 3, 4}; // 2. Query creation. // numQuery is an IEnumerable var numQuery = from num in numbers where (num % 2) == 0 select num; // 3. Query execution. foreach (int num in numQuery) { Console.Write("{0,1} ", num); }
LINQ – styl programowania var contacts = from c in customers where c.State == "WA" select new { c.Name, c.Phone }; class Contact { … }; List contacts = new List (); foreach(Customer c in customers) { if(c.State == WA) { Contact ct = new Contact(); ct.Name = c.Name; ct.Phone = c.Phone; contacts.Add(ct); }
Zapytania Składnia zbliżona do SQL Kompilowane do C# (dzięki Extension Methods) from id in source { from id in source | join id in source on expr equals expr [ into id ] | let id = expr | where condition | orderby ordering, ordering, … } select expr | group expr by key [ into id query ] Zaczyna się from Zero lub więcej from, join, let, where, orderby Kończy się select lub group by Opcjonalnie into
Zapytania Transformacja w wykonanie metody – Where, Join, OrderBy, Select, GroupBy, … from c in customers where c.State == "WA" select new { c.Name, c.Phone }; customers.Where(c => c.State == "WA").Select(c => new { c.Name, c.Phone });
LINQ to Objects Operatory mogą być użyte z każdą kolekcją(IEnumerable ) – Select, Where, GroupBy, Join, etc. Odroczona walidacja zapytania Wyrażenia Lambda using System; using System.Linq; using System.Collections.Generic; class app { static void Main() { string[] names = { "Burke", "Connor", "Frank", "Everett", "Albert, "George", "Harris", "David" }; Func filter = s => s.Length == 5; Func extract = s => s; Func project = s => s.ToUpper(); IEnumerable expr = names.Where(filter).OrderBy(extract).Select(project); foreach (string item in expr) Console.WriteLine(item); } BURKE DAVID FRANK
LINQ To In-Memory Objects LINQ To In-Memory Objectsjest używane do tworzenia zapytań do obiektów w każdym języku platformy.NET poprzez LINQ. Przykład: public class Person { public string FirstName { get; set; } public string LastName { get; set; } public int Age { get; set; } } //Create a list of person System.Collections.Generic.List lstPerson = new System.Collections.Generic.List { new Person { FirstName = "A", LastName = "X", Age = 15 }, new Person { FirstName = "B", LastName = "Y", Age = 17 }, new Person { FirstName = "C", LastName = "Z", Age = 24 } };
LINQ To In-Memory Objects - przykład Użycie metody rozszerzającej Where() pozwala na pobranie kolecji odpowiadającej zapytaniu. IEnumerable queryResult; queryResult = lstPerson.Where(p => p.FirstName.StartsWith("A")); Response.Write(queryResult.Count().ToString());//Total result count Response.Write(queryResult.First().FirstName);//Display First Name Response.Write(queryResult.First().LastName);//Display Last Name //Compute average age of person in list and display. Response.Write(person.Average(p => p.Age).ToString()); //Compute max age of person in list and display. Response.Write(person.Max(p => p.Age).ToString());
LINQ to DataSet DataSet w pełni zintegrowany z LINQ Działa dla DataSet typowanego i nietypowanego Łączenie, grupowanie danych w DataTable Tworzenie widoków na wielu DataTable Przykład: // Query Expression Syntax DataSet ds = new DataSet(); FillTheDataSet(ds);//Fill the DataSet. DataTable dtPeople = ds.Tables["People"]; IEnumerable query = from people In dtPeople.AsEnumerable() select people; foreach (DataRow p in query) Response.Write(p.Field (FirstName"));
LINQ to SQL Zapewnia mapowanie obiektowo - relacyjne (ORM) z.NET Framework dla baz Microsoft SQL Server Użycie silnie typowanych danych Zintegrowany dostęp do danych – Mapowanie tabel i wierszy na klasy i obiekty – Zbudowane na ADO.NET Mapowanie – Poprzez atrybuty lub zewnętrznie – Ręcznie lub poprzez designer – Relacje mapują się na properties Persistence – Sledzenie zmian – Aktualizacja poprzez SQL
LINQ to SQL Application SQL Server LINQ to SQL from c in db.Customers where c.City == "London" select c.CompanyName LINQ Query SQL Query SELECT CompanyName FROM Cust WHERE City = 'London' Rows ObjectsSubmitChanges() DML or Stored Procedures db.Customers.Add(c1); c2.City = Seattle"; db.Customers.Remove(c3); INSERT INTO Customers… UPDATE Customers … DELETE FROM Customers …
LINQ approach // First we will declare instance of DataContext class. // It is responsible for the translation of LINQ to SQL, and // the mapping of the results (rows) of that query to objects. // The DataContext can be equated to a database, in that it contains a series of tables // and stored procedures and views. CustomersDataContext dbCust = new CustomersDataContext(); var query = from p in dbCust.Customers where p.City == paris select p.Name, p.Country; foreach (var cust in query) { Response.Write(cust.Name); Response.Write(cust.Country); }
LINQ To SQL- select Select: Pobieranie wierszy jest osiągane poprzez pisanie zapytania w dowolnym języku oraz jego wykonanie. Za translację na zapytanie SQL odpowiedzialna jest warstwa LINQ to SQL Przykład: PersonDataClassesDataContext dbPeople = new PersonDataClassesDataContext(); var query = from p in dbPeople.Peoples where p.Age > 18 select p; foreach (var ppl in query) { Response.Write(ppl.FirstName); }
LINQ To SQL- insert Insert: Dodanie obiektów do stworzonego modelu,a następnie wywołanie SubmitChanges na stworzonym obiekcie DataContext. PersonDataClassesDataContext dbPeople = new PersonDataClassesDataContext(); People objPeople = new People(); objPeople.FirstName = "Gyan"; objPeople.LastName = "Singh"; objPeople.Age = 33; dbPeople.Peoples.InsertOnSubmit(objPeople); // At this point, the new People object is added in the object model. // In LINQ to SQL, the change is not sent to the database until SubmitChanges is called. dbPeople.SubmitChanges();
LINQ To SQL - update Update Query: Pobierany wartość z bazy i edytujemy jej wartość w przypisanym obiekcie. Po dokonaniu zmian wywołujemy SubmitChanges na obiekcie typu DataContext. Pryzkad: PersonDataClassesDataContext dbPeople = new PersonDataClassesDataContext(); var query = from p in dbPeople.Peoples select p; var intAge = 18; foreach (var ppl in query){ ppl.Age = intAge; intAge++; } dbPeople.SubmitChanges();
LINQ To SQL - delete Delete Query: Usuwamy obiekt z kolekcji, następnie wołamy SubmitChanges na obiekcie typu DataContext. Przykład: PersonDataClassesDataContext dbPeople = new PersonDataClassesDataContext(); var query = from p in dbPeople.Peoples where p.PersonID == 1 select p; if (query.Count() > 0) { dbPeople.Peoples.DeleteOnSubmit(query.First()); dbPeople.SubmitChanges(); }
LINQ to XML - System.Xml.Linq Stworzony by umożliwić korzystanie z XML bez konieczności poznawania Xpath/XSLT Stworzony na bazie standardowych zapytań LINQ Umożliwia przetwarzanie w pamięci dokumentu XML w celu pobrania kolekcji elementów i atrybutów Tworzenie zapytań z wieloma źródłami danych Możliwość użycia wyników jako parametrów dla Xelement lub Xattribute Tworzenie drzew XML Bardziej wydajne (mniejsze zużycie pamięci) Łatwiejszy i bogatszy niż niskopoziomowe sposoby
LINQ to XML Class Hierarchy
LINQ to XML - przykład TodayXmlDocument doc = new XmlDocument(); XmlElement contacts = doc.CreateElement("contacts"); foreach (Customer c in customers) if (c.Country == "USA") { XmlElement e = doc.CreateElement("contact"); XmlElement name = doc.CreateElement("name"); name.InnerText = c.CompanyName; e.AppendChild(name); XmlElement phone = doc.CreateElement("phone"); phone.InnerText = c.Phone; e.AppendChild(phone); contacts.AppendChild(e); } doc.AppendChild(contacts); Great Food … XElement contacts = new XElement("contacts", from c in customers where c.Country == "USA select new XElement("contact", new XElement("name", c.CompanyName), new XElement("phone", c.Phone) ) ); LINQ to XML
LINQ To XML - przykład AAA XXX ABB YYY CCC ZZZ
LINQ To XML – przykład //Using LINQ Extension Methods against an XML File XDocument people = //Casting to XElement System.Collections.Generic.IEnumerable xmlResult; xmlResult = people.Descendants("person").Where(p=>p.Element("firstname").Value.StartsWith("A")); //Total count of records. txtResultCount.Text = xmlResult.Count().ToString(); //Person First Name. txtPersonFirstName.Text = xmlResult.First().FirstNode; //Person Last Name. txtPersonLastName.text = xmlResult.First().LastNode; txtAvgAge.Text = people.Descendants("person").Average(p => Convert.ToInt32(p.Attribute("age").Value));
Korzyści z LINQ Zunifikowany dostęp do obiektów, obiektów relacyjnych, XML Sprawdzanie typów oraz wspacie IntelliSense Dostęp do funkcjonalności podobnych doSQL oraz Xquery z poziomu języka Rozszerzenia dla jezyków / API