language integrated query
DESCRIPTION
Language Integrated Query. Adam Furmanek [email protected]. Agenda. Nowy semestr Co to jest LINQ Delegaty Wyrażenia lambda Extension methods LINQ to SQL, LINQ to EF, LINQ to XML PLINQ Podsumowanie. Microsoft Student Partners. - PowerPoint PPT PresentationTRANSCRIPT
Language Integrated Query
Adam [email protected]
Agenda• Nowy semestr• Co to jest LINQ• Delegaty• Wyrażenia lambda• Extension methods• LINQ to SQL, LINQ to EF, LINQ to XML• PLINQ• Podsumowanie
Microsoft Student Partners• Ogólnoświatowy program zrzeszający
grupy .NET i IT• Setki uczelni• Tysiące członków
Historia programu• 2001 – wtedy wszystko się zaczęło• W ciągu 5 lat program działał w
piętnastu krajach• W końcu 2006 roku został
rozszerzony na 50 państw• Obecnie istnieje w ponad 100
krajach i ma niemal 3000 członków
Hierarchia• Ogólnoświatowym szefem programu
jest Michelle Fleming• APM w Polsce• SC dla Małopolski• SP AGH• WY!!!
Działalność grupy• Spotkania• Szkolenia• Certyfikaty• Staże i praktyki• IT Academic Day• ImagineCup• Code Camp• Noc z technologią
Co to jest LINQ?LINQ - .NET Language-Integrated
Query
• Zestaw deklaratywnych zapytań ogólnego przeznaczenia, służących do dostępu do różnych źródeł danych z aplikacji obiektowych.
Co to jest LINQ?• Technologia LINQ jest dostępna na
platformie Microsoft .Net Framework od wersji 3.5
• Aktualnie dostępna dla języków C# i Visual Basic.Net
• Dostępne porty dla Javy, PHP i JavaScriptu
• Wpływ na powstanie miał SQL i Haskell
Co to jest LINQ?• LINQ to zbiór operatorów zapytań
(ang. standard query operators) umożliwiających m.in.:– przeglądanie danych– filtrowanie/selekcje danych– projekcje danych
• LINQ udostępnia przyjazną, skrótową metodę zapisu operatorów zapytań
Projekt LINQJęzyk: C# Język: VB Inne języki…
.Net Language Integrated Query (LINQ)
Źródła danych LINQ
LINQ To Objects
LINQ To DataSets
LINQ To SQL
LINQ To Entities
LINQ To XML Inne…
Delegaty• Można je sobie wyobrażać jako
wskaźniki na funkcje• private delegate int Do (char x);• Mogą zawierać kilka metod• Jeżeli nie są void – zwracają wynik
ostatniej funkcjiDo transform;transform += method1;transform += method2;transform('5');
Wbudowane delegaty• Action:public delegate void Action<T>(T obj);Opcjonalnie przyjmuje parametr, nic nie zwraca• Func:public delegate TResult Func<TResult>();Opcjonalnie przyjmuje parametr i zwraca
Wyrażenia lambda• Nienazwana metoda zapisana w
miejscu delegata• (parameters) => expression-or-statement-
block• Można pominąć nawiasy, gdy jeden
parametrtransform += (c) => (int) c;
Closures• Wyrażenie lambda może
„przechwycić” lokalne zmienne• Wartości są obliczane dopiero przy
wykonywaniu wyrażeniaint factor = 2;Func<int, int> multiplier = n => n * factor;factor = 10;Console.WriteLine(multiplier(3)); // 30
Closures• Przechwycone zmienne w pętli
zachowuję się tak, jakby były deklarowane poza pętlą
Action[] actions = new Action[3];for (int i = 0; i < 3; i++) actions[i] = () => Console.Write(i);foreach (Action a in actions) a(); // 333
Closures• Dlaczego tak jest?
Action[] actions = new Action[3];int i = 0;actions[0] = () => Console.Write(i);i = 1;actions[1] = () => Console.Write(i);i = 2;actions[2] = () => Console.Write(i);i = 3;foreach (Action a in actions) a(); // 333
Closures• Jak sobie z tym poradzić? Skopiować
zmienną.
Action[] actions = new Action[3];for (int i = 0; i < 3; i++){ int loopScopedi = i; actions[i] = () => Console.Write(loopScopedi);}foreach (Action a in actions) a(); // 012
Closures• Wyrażenie lambda może zmieniać
przechwycone zmienneint seed = 0;Func<int> natural = () => seed++;Console.WriteLine(natural()); // 0Console.WriteLine(natural()); // 1Console.WriteLine(seed); // 2
Closures• Przechwycone zmienne żyją tak długo, jak długo żyje
wyrażeniestatic Func<int> Natural(){
int seed = 0;return () => seed++; // Returns a closure
}static void Main(){
Func<int> natural = Natural();Console.WriteLine(natural()); // 0Console.WriteLine(natural()); // 1
}
Extension methods• Służą do rozszerzania innych klas• Są zawsze statyczne• W pierwszym parametrze przyjmują
klasę do rozszerzenianamespace ExtensionMethods { public static class MyExtensions { public static int WordCount(this String str) { return str.Split(new char[] { ' ', '.', '?' }, StringSplitOptions.RemoveEmptyEntries).Length; } }}
Wbudowane extension methodspublic static bool Contains<TSource>(this IEnumerable<TSource> source, TSource value);
public static TSource First<TSource>(this IEnumerable<TSource> source);
public static int Max(this IEnumerable<int> source);
public static int Sum(this IEnumerable<int> source);
public static IEnumerable<TResult> Select<TSource, TResult>( this IEnumerable<TSource> source, Func<TSource, int, TResult> selector);
public static IEnumerable<TSource> Where<TSource>( this IEnumerable<TSource> source, Func<TSource, bool> predicate);
Co nam to daje?string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" };
IEnumerable<string> longerThanFour = names.Where(s => s.Length > 4);
foreach(string s in longerThanFour){ Console.WriteLine(s);}
Co nam to daje?string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" };
IEnumerable<string> query = names .Where(n => n.Contains("a")) .OrderBy(n => n.Length) .Select(n => n.ToUpper());
foreach (string name in query) Console.WriteLine(name);
JAYMARYHARRY
Jak to działa?
LINQ to Objects• Operują na danych lokalnych• Składnią przypominają SQLstring[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" };IEnumerable<string> query = from n in names where n.Contains("a") // Filter elements orderby n.Length // Sort elements select n.ToUpper(); // Translate each element (project)foreach (string name in query) Console.WriteLine(name);
LINQ to Objects• n jest tak zwaną range-variable• Wyrażenie LINQ jest kompilowane do
extension methods• Deferred Execution - Wyrażenie jest
wykonywane dopiero w momencie wykorzystania wyniku – wyjątkiem są wyrażenia zwracające coś innego od IEnumerable<>
Jak działa Deferred Execution
Mieszanie składnistring[] names = { "Tom", "Dick", "Harry",
"Mary", "Jay" }; int matches = ( from n in names where n.Contains("a") select n) .Count(); // 3
var• Czasami może być trudno określić
typ zwracany przez funkcję• Albo po prostu jesteśmy leniwi i nie
chce się nam określać typu• Z pomocą przychodzi varvar a = 3;
Typy anonimoweclass TempProjectionItem{ public string Original; // Original name public string Vowelless; // Vowel-stripped name}string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" };IEnumerable<TempProjectionItem> temp = from n in names select new TempProjectionItem { Original = n, Vowelless = n.Replace("a", "").Replace("e","") .Replace("i", "") .Replace("o", "") .Replace("u", "") };
Typy anonimowevar query = from n in names select new { Original = n, Vowelless = n.Replace ("a", "") .Replace ("e", "") .Replace ("i", "") .Replace ("o", "") .Replace ("u", "")};
LINQ to SQL[Table(Name=”Customers”)]public class Customer{
[Column(IsPrimaryKey = true)]public int ID;
[Column]public string Name;
}
LINQ to SQLpublic class MyDataContext : DataContext{
public static string DBConnectionString = "Data Source=isostore:/ToDo.sdf";
public MyDataContext(string connectionString) : base(connectionString)
{ }
public Table<Customer> customers;}
SQLMETAL• Ręczne mapowanie tabel na klasy
może być trudne• Zajmuje dużo czasu• Łatwo o błąd• Rozwiązanie - SQLMETAL
SQLMETAL
• Można wybrać język• Można zmienić namespace• Można wygenerować DataContext• Sam tworzy liczby mnogie (po
angielsku)• Są nakładki graficzne
sqlmetal baza /code:wynik /language:csharp /namespace:nazwaNS /context:nazwaDC /pluralize
LINQ to EF[TEdmEntityType(NamespaceName = "NutshellModel", Name = "Customer")]Public partial class Customer{
[EdmScalarPropertyAttribute (EntityKeyProperty = true, IsNullable = false)]
public int ID;
[EdmScalarProperty (EntityKeyProperty = false, IsNullable = false)]
public string Name;}
Entity Framework• Nie pytamy bazy – pytam Entity Data
Model• Potrzebujemy Conceptual Model
(opisuje EDM)• Store Model (opisuje Database
Schema)• Mapping (jak się ma CM do SM)
Entity Framework• Ręczne tworzenie klas może być
nudne i błędogenne (jak zawsze)• W Visual Studio możemy dodać
projekt ADO.NET Entity Data Model• Stworzy on plik konfiguracyjny i
wszystkie klasy
Entity Framework• Możemy mapować wiele tabel na
jedną encję• Możemy mapować jedną tabelę na
wiele encji• Podejście Table per hierarchy• Table per type• Table per concrete type
Jak to działa• Dotychczas nasze LINQ działały na
obiektach lokalnych – były to local queries
• Aby skorzystać z bazy używamy expression trees
• Wykorzystujemy do tego interfejs IQueryable i fluent syntax
Jak to działa• IQueryable<string> query = (
from c in customers where c.Name.Contains("a") orderby c.Name.Length select c.Name.ToUpper());
• IQueryable<string> query= customers.Where(c => c.Name.Contains("a")).OrderBy(c => c.Name.Length).Select(c => c.Name.ToUpper());
• Następnie kompilator dopasowuje funkcje do interfejsu IEnumerable lub IQueryable
• Wybiera ten drugi i tworzy drzewo wywołań, które jest interpretowane w trakcie wykonania (a nie kompilacji)
Jak to działa
Expression Trees• Expression trees można mieszać z
local queries• Są leniwe• Metoda AsEnumerable
LINQ to XML• Wykorzystuje DOM (a właściwie X-
DOM)• Wykorzystuje interfejs IEnumerable• Jest zgodne z wytycznymi W3C
string xml = @"<customer id='123' status='archived'><firstname>Joe</firstname>
<lastname>Bloggs<!--nice name--></lastname></customer>";
PLINQ• Automatycznie „wielowątkuje”
zapytanie• Działa jedynie z LINQ to Objects!• AsParallel• AsSequential• AsOrdered / AsUnordered• WithDegreeOfParallelism• AggregateException
PrzykładIEnumerable<int> numbers = Enumerable.Range(3, 100000 - 3);var parallelQuery =from n in numbers.AsParallel()where Enumerable.Range(2, (int)Math.Sqrt(n)).All(i => n % i > 0)select n;
Linki• http://
msdn.microsoft.com/en-us/library/bb397926.aspx
• http://msdn.microsoft.com/en-us/library/bb386976.aspx
• http://msdn.microsoft.com/en-us/library/bb386964.aspx
• Albo po prostu bingować
Pytania?
Sprawy organizacyjne• Rejestracja na Code Guru• Wybór terminu spotkań• Konkurs Geek Club• Praca• Projekty• Piwo