MICROSOFT LINQ Susanna Salonen Huhtikuu 2008
1 SISÄLTÖ 1 TIIVISTELMÄ... 2 2 JOHDANTO... 3 3 MIKÄ ON LINQ?... 3 4 LINQ:N OSA-ALUEET... 5 4. 1 LINQ to Objects... 6 4. 2 LINQ to ADO.NET... 6 4.3 LINQ to XML... 7 5 OBJECT-RELATIONAL MAPPING (ORM)... 7 6 LINQ TO SQL... 9 6.1 LINQ To SQL käytännössä - osa 1... 9 6.2 LINQ To SQL käytännössä - osa 2... 21 7 LISÄTIETOJA LINQ:STA... 28 8 YHTEENVETO... 29 LÄHTEET... 31
2 1 TIIVISTELMÄ Työn tavoitteena oli selvittää, mikä on Microsoft LINQ, mistä eri osa-alueista se koostuu ja kuinka sitä voidaan hyödyntää kyselyiden tekemisessä tietokantaan, XML - muodossa olevaan dataan tai muistissa oleviin objekteihin. Tavoitteena oli myös etsiä käytännön kokemuksia LINQ:n käytöstä ohjelmistoprojekteissa, ja listata sen pohjalta LINQ:n hyviä ja huonoja puolia. Lisäksi kerättiin linkkejä erilaisiin LINQ:ta käsitteleviin sivustoihin, joiden avulla on helppo lähteä tutustumaan LINQ -tekniikkaan syvemmin. Selvityksessä LINQ:ta verrattiin perinteiseen sulautettuun SQL:ään. Selvitystyö tehtiin pitkälti LINQ:sta julkaistun sähköisen materiaalin pohjalta etsimällä tietoa edellä esitettyihin asioihin. Selvitystyön perusteella voidaan todeta, että LINQ:ssa on monia hyviä puolia verrattuna perinteiseen sulautetun SQL:n käyttöön ohjelmoinnissa ja sillä voidaan tehdä ohjelmointityöstä paljon aiempaa tehokkaampaa ja ohjelmakoodista ylläpidettävämpää. Selvitystyö kuitenkin osoitti, että tehokkuutta ei saada paranemaan, ellei LINQ:ta osata hyödyntää oikeaoppisesti tai tuntematta sen rajoitteita. Jos LINQ:ta käytetään ainoastaan sulautetun SQL:n korvikkeena, jäävät uuteen tekniikkaan siirtymisestä syntyvät hyödyt vähäisiksi
3 2 JOHDANTO Tämä selvitysraportti tehtiin keväällä 2008 Jyväskylän ammattikorkeakoulun tietokantojen suunnittelu ja tietokantojen hallinta -kurssien harjoitustyönä. Selvitysraportissa perehdyttiin Microsoftin tekniikkaan yhdistää olio-ohjelmointi ja relaatiotekniikat. Tämä tekniikka nimeltä LINQ (Language Integrated Query) julkaistiin lopullisesti Microsoft Visual Studio 2008:n ja.net Framework 3.5:n mukana. LINQ mahdollistaa erilaisten tietolähteiden, kuten tietokannan, xml -tiedostojen tai itse luotujen olioiden käytön ohjelmakoodissa samanlaisella hakusyntaksilla. Tähän selvitysraporttiin pyrittiin kokoamaan LINQ:n hyviä puolia, ja kertomaan esimerkein, kuinka LINQ:ta voidaan hyödyntää ohjelmoinnissa. Tarvittava ympäristö LINQ kokeiluiden tekemistä varten asennettuna täytyy olla Microsoft Visual Studio 2008 ja.net Framework 3.5. Ennen kehitysympäristön asentamista, kannattaa asentaa.net Framework 3.5 osoitteesta: http://www.microsoft.com/downloads/details.aspx?familyid=333325fd-ae52-4e35-b531-508d977d32a6&displaylang=en (viitattu 11.4.2008). Visual Studio 2008 Express version voi ladata osoitteesta: http://www.microsoft.com/express/default.aspx (viitattu 11.4.2008). Opiskelijat on mahdollisuus ladata myös Visual Studio 2008:n Professional -versio Microsoftin DreamSparkista: https://downloads.channel8.msdn.com (viitattu 11.4.2008). Sekä kehitysympäristön, että Framework:n voi ladata ilmaiseksi. 3 MIKÄ ON LINQ? LINQ on ohjelmointimalli, joka tarjoaa täysin uudenlaisen tavan kyselyiden tekemiseen ja datan käsittelyyn Microsoftin.NET projekteissa. LINQ pyrkii eroon tavallisen sulautetun sql -kielen mukanaan tuomista rajoitteista ja samalla kasvattamaan oh-
4 jelmointityön tuottavuutta, tarjoamalla lyhyemmän, mielekkäämmän ja ilmaisuvoimisen syntaksin datan käsittelyyn. (Pialorsi & Russo 2007, 2.) Tässä esimerkiksi tyypillinen tilanne, jossa ohjelmallisesti haetaan kaikki suomalaisten yritysasiakkaiden nimet tietokannasta: var query = from c in Customers where c.country == "Finland" select c.companyname; Kyselystä voi heti huomata eron normaaliin sql:n syntaksiin. Sql -kyselyssä luetellaan ensin tietokannan sarakkeet, jotka kyselyyn otetaan mukaan, ja vasta tämän jälkeen kerrotaan taulun nimi, josta tiedot haetaan. LINQ:ssa kyselyä lähdetään muodostamaan valitsemalla ensin taulu, ja ehdot joiden perusteella tietoa taulusta haetaan. Vasta tämän jälkeen valitaan tarpeelliset sarakkeet. Näin kyselyyn voidaan rajata juuri tarpeellinen ja vain tarpeellinen tulosjoukko, mikä helpottaa ohjelmointityötä huomattavasti. Edellisen kyselyn tulokset ovat suoraan merkkijonoina, jotka saadaan tulostettua esim. foreach -rakenteella: foreach (string name in query) { Console.WriteLine(name); } Tällä samalla tavalla voidaan tehdä kysely niin SQL Server -tietokantaan, DataSet:iin, muistissa oleviin taulukoihin tai moneen muun laiseen dataan. Esimerkiksi Customers voisi olla kokoelma objekteja: Customer[] Customers; Tai esimerkiksi DataTable DataSet:n sisällä: DataSet ds = GetDataSet(); DataTable Customers = ds.tables["customers"]; Customers voisi olla luokka, joka kuvaa fyysisen relaatiotietokannan taulun:
5 DataContext db = new DataContext(ConnectionString); Table<Customer> Customers = db.gettable<customer>(); Ja se voi olla käsitteellinen luokka, joka on mapattuna suoraan relaatiotietokantaan: NorthwindModel datamodel = new NorthwindModel(); ObjectQuery<Customer> Customers = datamodel.customers; LINQ mahdollistaa kyselyn tekemisen yhtäaikaa monen tyyppiseen dataan. Voidaan esim. yhdistää muistissa olevien objektien tietoja ja tietokannasta haettavia tietoja keskenään ja kohdistaa yhdistettyyn dataan haluttuja hakuja. Tämä on erittäin joustava tapa käsitellä tietoa, mutta vielä tällähetkellä äärimmäisen tehoton. Joten kaupallista sovellusta ohjelmoitaessa on tarkkaan mietittävä kannattaako mahdollisuutta erityyppisen datan yhdistämiseen hyödyntää. (Launiala 2008.) 4 LINQ:N OSA-ALUEET Kuviossa 1 on kuvattu, LINQ:n eri osa-alueet, joita ovat LINQ to Objects, LINQ to ADO.NET ja LINQ to XML. LINQ to ADO.NET jakautuu vielä kolmeen aliryhmään, joita ovat LINQ to sql, LINQ to DataSet ja LINQ to Entities. KUVIO 1. LINQ.NET Framework 3.5:ssa
6 4. 1 LINQ to Objects LINQ to Objects käsittää nimensä mukaisesti oliokokoelmien käsittelyn ohjelmakoodissa. Olioiden ei tarvitse olla itse luotuja, kuten seuraavasta ohjelmakoodista voidaan nähdä. Ohjelmakoodissa haetaan kaikki käyttöjärjestelmän Temp -hakemistossa olevat tiedostot, joiden koko on yli 10000 tavua ja järjestetään haun tulokset koon mukaan. (Pialorsi & Russo 2007, 15.) string temppath = Path.GetTempPath(); DirectoryInfo dirinfo = new DirectoryInfo(tempPath); var query = from f in dirinfo.getfiles() where f.length > 10000 orderby f.length descending select f; 4. 2 LINQ to ADO.NET LINQ to ADO.NET on LINQ:n kiinnostavin osa tietokantojen näkökulmasta. Kuten edellä todettiin, LINQ to ADO.NET jakautuu edelleen kolmeen osaan. LINQ to Sql hallitsee mappauksen ohjelmakoodin ja fyysisen tietokantataulun välillä. LINQ to Entities on hyvin samankaltainen kuin LINQ to Sql. Sen sijaan, että käytettäisiin suoraa fyysistä tietokantaa, LINQ to Entities käyttää abstraktia Entity Data Model:a (EDM). Tuloksena on abstrakti taso, joka erotettu fyysisestä datatasosta. LINQ to DataSet taas on juuri sitä, mistä nimikin kertoo, eli tapa tehdä kysellä tietoja Data- Set:sta LINQ:ta käyttäen. LINQ to ADO.NET:a esitellään vielä myöhemmin lisää. Tässä esimerkki LINQ to DataSet:sta, jossa on yhdistetty kahden DataTable:n sisältö. (Pialorsi & Russo 2007, 15-16.) DataSet ds = LoadDataSetUsingDataAdapter(); DataTable orders = ds.tables["orders"]; DataTable orderdetails = ds.tables["orderdetails"]; var query = from o in orders.asenumerable() join od in orderdetails.asenumerable() on o.field<int>( "OrderID" ) equals od.field<int>("orderid") into orderlines where o.field<datetime>( "OrderDate" ).Year >= 1998 orderby o.field<datetime>( "OrderDate" ) descending select new { OrderID = o.field<int>( "OrderID" ), OrderDate = o.field<datetime>( "OrderDate" ), Amount = orderlines.sum( od => od.field<decimal>( "UnitPrice" )
7 * od.field<short>( "Quantity" ) ) }; 4.3 LINQ to XML LINQ to XML tarjoaa hieman erilaisen tavan XML -muotoisen datan kanssa työskentelyyn, kuten XML -datasta tehtäviin kyselyihin ja XML-datan muokkaukseen..net kielistä erityisesti Visual Basic 9.0 sopii erinomaisesti XML datan käsittelyyn, koska kieleen on sisällytetty XML:n literaaleja. Tämä ominaisuus tekee hankalasta XMLtiedostojen käsittelystä paljon helpompaan. Esimerkki, jossa XML -dataan tehdään kysely LINQ:lla: (Pialorsi & Russo 2007, 16.) var customersfromxml = from c in xmlcustomers.elements("customer") where (String)c.Attribute("country") == "Italy" orderby (String)c.Element("name") select new { Name = (String)c.Element("name"), City = (String)c.Attribute("city") }; foreach (var customer in customersfromxml) { Console.WriteLine(customer); } 5 OBJECT-RELATIONAL MAPPING (ORM) LINQ ei ole pelkästään kyselykieli vaan täysverinen olio-relaatio -muunnin (object relational mapper). On turhaa käyttää LINQ:ta pelkästään sulautetun SQL:n korvikkeena hyödyntämättä sen ominaisuuksia tietokannan käsittelyssä. (Launiala 2008.) Mikä sitten on olio-relaatio -muunnos? Käytännössä se tarkoittaa olioiden automaattista tallentamista ja lataamista relaatiotietokantaan eli tavanomaisesta tietokannan käsittelystä tulee olioiden ohjelmointia. Olio-relaatio -muuntimia käyttämällä ei ohjelmakoodiin tarvitse enää upottaa SQL -lauseita, koska muunnin kirjoittaa ne itse. Kuviossa 2 nähdään, kuinka tuottavuus tietokantaan pohjautuvien sovellusten teossa
8 huononee, jos käytetään normaalia SQL:ää, eikä puhdasta olio-ohjelmointia - tuottavuudessa palataan kahdeksankymmentä luvun tasolle. (Bernstein 1997, 233 242.) KUVIO 2. Objekti-relaatio -muuntimen hyöty Kun käytetään olio-relaatiomuunnosta, voidaan ohjelmoida aidosti olio-ohjelmoinnin sääntöjen mukaan, ohjelmakoodin määrää pienenee, koodin ylläpidettävyys kasvaa ja ohjelmointivirheiden, sekä kantaan asti menevän huonon ja väärän datan määrä vähenee. Samoin vältytään kahden ohjelmointikielen käyttämistä samassa sovelluksessa (Kalima 2004). Olio-relaatio -muunnosta kannattaa käyttää sovelluksissa, jotka perustuvat täysin tietokannan käyttöön tämän tapaisia ovat suurin osa liiketoimintaa tukevista ja ohjaavista sovelluksista. Yleensä sovelluksen pystyy tekemään tehokkaasti ORM - tekniikkaa hyödyntäen. Jos tehokkuus osoittautuu pullonkaulaksi, voidaan osa kyselyistä tehdä normaalia SQL -syntaksia käyttäen, esim. tilanteessa, jossa halutaan optimoida käsin tietokantahakuja (Kalima 2004).
9 6 LINQ TO SQL LINQ To SQL on Microsoftin tapa toteuttaa olio-relaatio -muunnin. LINQ To SQL tuo tarjoaa kaikki edellisessä luvussa esille tulleet olio-relaatio -muuntimen hyvät puolet. LINQ To SQL:n käyttäminen edellyttää, että käytössä tietokanta on täysin relaatiopohjainen. Tällä hetkellä tukea ei myöskään löydy kuin Microsoft SQL Servereille, joten tämä hieman rajoittaa LINQ To SQL:n käyttöä kaupallisissa sovelluksissa. (Launiala 2008.) 6.1 LINQ To SQL käytännössä - osa 1 Seuraavassa on esimerkkiharjoitus, jolla avulla voi tutustua LINQ To SQL:ään käytännön kautta. Esimerkin runko on englanninkielisenä (Learning by Walkthroughs (LINQ to SQL)) osoitteessa: http://msdn2.microsoft.com/en-us/library/bb399349.aspx (viitattu 13.4.2008). 1. Luo koneellesi harjoitusta varten kansio: c:\linqtest. 2. Lataa Northwind -tietokanta osoitteesta: http://msdn2.microsoft.com/enus/library/bb399411.aspx (viitattu 12.4.2008) vaiheessa 1 luomaasi kansioon. Huom. jos koneellasi ei ole SQL Serveriä, lataa ja asenna myös SQL Server Express Edition. Sen löydät Microsoftin Download Centerista: http://www.microsoft.com/downloads/ (viitattu 12.4.2008). 2. Käynnistä Microsoft Visual Studio 2008 ja luo uusi VB.net -projekti. Katso mallia kuviosta 3.
10 KUVIO 3. Uuden projektin luominen 3. Lisätään tarvittavat viittaukset. Avaa Solution Explorer, paina projektin nimen paella hiiren oikeaa painiketta, ja valitse References ja tämän jälkeen Add Reference. Liitä projektiin System.Data.Linq ja System.Windows.Forms. Katso mallia kuviosta 4. KUVIO 4. Viittausten lisääminen projektiin
11 4. Kirjoita ennen moduulin alkua seuraavat rivit (katso mallia kuviosta 5): Imports System.Data.Linq Imports System.Data.Linq.Mapping Imports System.Windows.Forms KUVIO 5. Tarvittavien kirjastojen lisääminen ohjelmaan 5. Lisätään uusi luokka, joka on mapattuna tietokannan Customers -tauluun. Lisää seuraavat rivit Sub Main():n alapuolelle (katso mallia kuviosta 6): <Table(Name:="Customers")> _ Public Class Customer Private _CustomerID As String
12 KUVIO 6. Tietokantaan mapatun luokan lisääminen ohjelmaan 6. Lisätään luodun Customer -luokan sisälle viittaukset Customers -taulun sarakkeisiin. Katso mallia kuviosta 7. Private _CustomerID As String <Column(IsPrimaryKey:=True, Storage:="_CustomerID")> _ Public Property CustomerID() As String Get Return Me._CustomerID End Get Set(ByVal value As String) Me._CustomerID = value End Set End Property Private _City As String <Column(Storage:="_City")> _ Public Property City() As String Get Return Me._City End Get Set(ByVal value As String) Me._City = value End Set End Property
13 KUVIO 7. Customers -taulun sarakkeiden lisääminen ohjelmakoodiin 7. Lisätään tietokanta -yhteys. Kirjoita seuraavat rivit Sub Main -metodin sisään (katso mallia kuviosta 8): ' Use a connection string. Dim db As New DataContext _ ("c:\linqtest\northwnd.mdf") ' Get a typed table to run queries. Dim Customers As Table(Of Customer) = _ db.gettable(of Customer)()
14 KUVIO 8. Tietokanta -yhteyden lisääminen ohjelmaan 8. Tehdään yksinkertainen kysely tietokantaan. Kirjoita seuraavat rivit Sub Main - metodiin Table(Of Customer) -määrityksen alapuolelle (katso mallia kuviosta 9). ' Attach the log to show generated SQL in a console window. db.log = Console.Out ' Query for customers in London. Dim custquery = _ From cust In Customers _ Where cust.city = "London" _ Select cust
15 KUVIO 9. Kyselyn lisääminen ohjelmaan 9. Lisätään ohjelmakoodi tietokantakyselyn tulosten esittämiseksi MessageBox:ssa. Kirjoita seuraavat rivit Sub Main -metodin loppuun (katso mallia kuviosta 10): ' Format the message box. Dim msg As String = "", title As String = "London customers:", _ response As MsgBoxResult, style As MsgBoxStyle = _ MsgBoxStyle.Information ' Execute the query. For Each custobj In custquery msg &= String.Format(custObj.CustomerID & vbcrlf) Next ' Display the results. response = MsgBox(msg, style, title)
16 KUVIO 10. Tietokantahaun tulostaminen MessageBoxiin 10. Aja ohjelma F5:lla. Kuviossa 11 on haun tulokset. KUVIO 11. Tietokantahaun tulokset 11. Lisätään uusi luokka nimeltä Order. Kirjoita seuraavat rivit ohjelmakoodiin Customer -luokan perään. Huomaa, että ohjelmakoodissa määritellään yhteys Orders - taulun CustomerID -sarakkeen ja Customers -taulun CustomerID:n välille.
17 <Table(Name:="Orders")> _ Public Class Order Private _OrderID As Integer Private _CustomerID As String Private _Customers As EntityRef(Of Customer) Public Sub New() Me._Customers = New EntityRef(Of Customer)() End Sub _ <Column(Storage:="_OrderID", DbType:="Int NOT NULL IDENTITY", IsPrimaryKey:=True, IsDBGenerated:=True)> _ Public ReadOnly Property OrderID() As Integer Get Return Me._OrderID End Get End Property ' No need to specify a setter because IsDBGenerated is true. <Column(Storage:="_CustomerID", DbType:="NChar(5)")> _ Public Property CustomerID() As String Get Return Me._CustomerID End Get Set(ByVal value As String) Me._CustomerID = value End Set End Property <Association(Storage:="_Customers", ThisKey:="CustomerID")> _ Public Property Customers() As Customer Get Return Me._Customers.Entity End Get Set(ByVal value As Customer) Me._Customers.Entity = value End Set End Property End Class 12. Kirjoita seuraavat rivit Customer luokkaan merkiksi Customers ja Orders - taulun välisestä yhteydestä (katso mallia kuviosta 12): Private _Orders As EntitySet(Of Order) Public Sub New() Me._Orders = New EntitySet(Of Order)() End Sub <Association(Storage:="_Orders", OtherKey:="CustomerID")> _ Public Property Orders() As EntitySet(Of Order) Get Return Me._Orders End Get Set(ByVal value As EntitySet(Of Order)) Me._Orders.Assign(value) End Set End Property
18 KUVIO 12. Yhteyden merkitseminen Customers- ja Orders taulujen välille 13. Kirjoita Sub Main -metodiin kysely, jossa haetaan tietoa Orders taulusta suoraan Customer olion kautta: ' Query for customers who have no orders. Dim custquery = _ From cust In Customers _ Where Not cust.orders.any() _ Select cust Dim msg As String = "", title As String = _ "Customers With No Orders", response As MsgBoxResult, _ style As MsgBoxStyle = MsgBoxStyle.Information For Each custobj In custquery msg &= String.Format(custObj.CustomerID & vbcrlf) Next response = MsgBox(msg, style, title) 14. Aja ohjelma F5:lla. Kuviossa 13 on haun tulokset.
19 KUVIO 13. Haun tulokset 15. Lisätään Sub Main metodin perään uusi luokka Northwind joka on peritty DataContext luokasta. Tällätavoin tietokannan taulujen käyttö ohjelmassa on helpompaa ja yksinkertaisempaa. Public Class Northwind Inherits DataContext ' Table(Of T) abstracts database details per ' table/data type. Public Customers As Table(Of Customer) Public Orders As Table(Of Order) Public Sub New(ByVal connection As String) MyBase.New(connection) End Sub End Class 16. Muutetaan Main Sub metodia käyttämään edellä luotua Northwind -luokkaa (katso mallia kuviosta 14): ' Use a connection string. Dim db As New Northwind _ ("C:\Linqtest\northwnd.mdf") ' Query for customers from Seattle. Dim custs = _ From cust In db.customers _ Where cust.city = "Seattle" _ Select cust For Each custobj In custs Console.WriteLine("ID=" & custobj.customerid) Next ' Freeze the console window. Console.ReadLine()
20 KUVIO 14. Helpompi tapa tehdä haku tietokannasta. 17. Aja ohjelma F5:lla. Kuviossa 15 on haun tulos. KUVIO 15. Haun tulos
21 6.2 LINQ To SQL käytännössä - osa 2 Seuraavassa on kuvattu, kuinka sql -tietokannassa olevaa tietoa voidaan muuttaa. 1. Generoidaan VB.NET tiedosto tietokannan pohjalta SQLMETAL ohjelmaa käyttäen. SQLMETAL -ohjelmasta löytyy tietoa Microsoftin sivuilta: http://msdn2.microsoft.com/en-us/library/bb386987.aspx. Oletuksena ohjelma löytyy koneelta kansiosta: drive:\program Files\Microsoft SDKs\Windows\vn.nn\bin (katso kuvio 16). KUVIO 16. SQLMETAL -ohjelman sijainti 2. Aja komentokehotteessa seuraava rivi (katso mallia kuviosta 17): sqlmetal /code:"c:\linqtest\northwind.vb" /language:vb "C:\linqtest\northwnd.mdf" /pluralize
22 KUVIO 17. SQLMETAL -ohjelman käyttäminen 2. Tee uusi VB.NET -projekti. Katso mallia kuviosta 18. KUVIO 18. Uuden VB.NET -projektin luominen
23 3. Lisää viittaus System.Data.Linq projektiin (Solution Explorer > References > Add Reference (katso mallia kuviosta 19). Ja kirjoita ennen Module1:sta seuraavat rivit: Imports System.Data.Linq Imports System.Data.Linq.Mapping KUVIO 19. Tarvittavien kirjastojen tuominen ohjelmaan 3. Liitä SQLMETAL -ohjelmalla generoitu ohjelmakoodi projektiin valitsemalla projektin nimen päällä Add Existing Item ja valitsemalla northwind.vb -tiedosto (katso mallia kuviosta 20).
24 KUVIO 20. Generoidun ohjelmakoodin liittäminen projektiin 4. Luodaan tietokantayhteys. Kirjoita seuraavat rivit Sub Main -metodin sisään (katso mallia kuviosta 21): ' Use a connection string, but connect to ' the temporary copy of the database. Dim db As New Northwnd _ ("C:\Linqtest\northwnd.mdf") ' Keep the console window open after activity stops. Console.ReadLine()
25 KUVIO 21. Tietokantayhteyden luominen 5. Kirjoita seuraavat rivit Sub Main -metodiin ennen Console.ReadLine() riviä. Ohjakoodi luo uuden rivin Customers -tauluun ja tulostaa taulussa olevat CustomerID:t, jotka sisältävät merkkijonon CA, ennen uuden rivin lisäystä tietokantaan. Katso mallia kuviosta 22. ' Create the new Customer object. Dim newcust As New Customer() newcust.companyname = "AdventureWorks Cafe" newcust.customerid = "A3VCA" ' Add the customer to the Customers table. db.customers.insertonsubmit(newcust) Console.WriteLine("Customers matching CA before insert:") Dim custquery = _ From cust In db.customers _ Where cust.customerid.contains("ca") _ Select cust For Each cust In custquery Console.WriteLine("Customer ID: " & cust.customerid) Next
26 KUVIO 22. Ohjelmakoodi, joka lisää uuden rivin Customers -tauluun 6. Aja ohjelma F5:lla. Kuviossa 23 on haun tulos. KUVIO 23. Haun tulos 7. Kirjoita seuraavat rivit, jotka päivittävät ContactName:n Customers -taulussa CustomerID:n perusteella Sub Main -metodiin ennen Console.ReadLine() riviä: Dim existingcust = _ (From cust In db.customers _ Where cust.customerid = "ALFKI" _
27 Select cust).first() ' Change the contact name of the customer. existingcust.contactname = "New Contact" 8. Kirjoita seuraavat rivit, jotka poistavat rivin Order Details -taulusta Sub Main - metodiin ennen Console.ReadLine() -riviä: ' Access the first element in the Orders collection. Dim ord0 As Order = existingcust.orders(0) ' Access the first element in the OrderDetails collection. Dim detail0 As OrderDetail = ord0.orderdetails(0) ' Display the order to be deleted. Console.WriteLine _ (vbcrlf & "The Order Detail to be deleted is: OrderID = " _ & detail0.orderid) ' Mark the Order Detail row for deletion from the database. db.orderdetails.deleteonsubmit(detail0) 9. Kirjoita seuraava rivi, joka vie muutokset tietokantaan Sub Main -metodiin ennen Console.ReadLine() -riviä: db.submitchanges() 10. Kirjoita seuraavat rivit Sub Main -metodiin ennen Console.ReadLine() riviä. Näin ohjelma tulostaa tilanteen tietokannassa edellisen lisäyksen, päivityksen ja poiston jälkeen. Console.WriteLine(vbCrLf & "Customers matching CA after update:") Dim finalquery = _ From cust In db.customers _ Where cust.customerid.contains("ca") _ Select cust For Each cust In finalquery Console.WriteLine("Customer ID: " & cust.customerid) Next 11. Aja ohjelma F5:lla. Kuviossa 24 on ohjelman tulostamat tiedot.
28 KUVIO 24. Ohjelman tulostamat tiedot. Edellä kuvattujen esimerkkien avulla, pääsee helposti ja turvallisesti tutustumaan LINQ To SQL:n perusteisiin. Näiden jälkeen voi kokeilla konsoliohjelma sijasta pienen Windows -sovelluksen tekoa: http://msdn2.microsoft.com/enus/library/bb386955.aspx (viitattu 13.4.2008). 7 LISÄTIETOJA LINQ:STA Koska LINQ on varsin uusi tekniikka, ei suomenkielistä materiaalia aiheesta juuri löydy. Helpoiten LINQ:n saloihin pääsee tutustumaan http://www.asp.net/learn/linqvideos/ -sivuston videoiden avulla (viitattu 11.4.2008). Lisäksi artikkeli http://visualstudiomagazine.com/features/article.aspx?editorialsid=1340 antaa hyvän yleiskuvan aiheesta (viitattu 11.4.2008). Jos fokuksena on kaikki mahdollinen LINQ:sta A:sta Ö:hön, niin helposta tiedonjanoon löytyy Microsoftin omilta LINQ - projektin sivuilta: http://msdn2.microsoft.com/en-us/netframework/aa904594.aspx (viitattu 11.4.2008). Scott Guthrie:n blogista löytyy todella hyvää lisätietoa ja vinkkejä. Scottin blobi on muutoinkin loistava ajankohtaisen tiedon lähde: http://weblogs.asp.net/scottgu/archive/tags/linq/default.aspx (viitattu 11.4.2008).
29 Microsoft Visual Studio 2008:sta ja.net 3.5:sta löytyy ilmainen Training Kit materiaali osoitteesta: http://www.microsoft.com/downloads/details.aspx?familyid=8bdaa836-0bba- 4393-94DB-6C3C4A0C98A1&displaylang=en (viitattu 11.4.2008). Materiaalista löytyy myös harjoituksia LINQ:sta. On huomioitava, että harjoitukset vaativat toimiakseen mm. SQL Server 2005:n. 8 YHTEENVETO Tämän selvityksen tarkoituksena oli selvittää, mikä LINQ, mistä osista se koostuu ja onko sen käytöstä hyötyä. Lisäksi pyrittiin etsimään käytännön kokemuksia LINQ:n käytöstä oikeissa ohjelmistoprojekteissa ja kokoamaan erilaisia lähteitä, joiden avulla pääsee tutustumaan LINQ:n sielunelämään ja mahdollisuuksiin syvällisemmin. Käytännön kokemuksia LINQ:sta voi kuunnella ProtonIT Oy:n konsultti Kalle Launialan Microsoft Developer Days 2008:ssa pitämästä luennosta (Launiala 2008). Tämä selvitysraportti on pieni pintaraapaisu LINQ:n mahdollisuuksiin, koska LINQ:ta voi hyödyntää monenlaisten tietolähteiden käytössä. Ehkä suurin uudistus verrattuna vanhaan, on objekti-relaatio muunnoksen mahdollisuus LINQ To SQL:ää käyttäen, mistä johtuen selvitysraporttiin sisällytettyjen harjoitusten kohteeksi valittiin juuri LINQ To SQL. Kaikki linkit LINQ:sta kertoviin lisämateriaaleihin pyrittiin valitsemaan mahdollisimman hyvin itseopiskeluun sopiviksi. Ongelmana selvitysraportin teossa oli suomenkielisen materiaalin puute. Koska materiaalia ei juuri suomeksi löytynyt, oli englanninkielisten termien kääntäminen suomeksi varsin haasteellista. Työ kuitenkin osoitti, että LINQ:ssa ja etenkin LINQ To SQL:ssä on potentiaalia. Ohjelmointityössä on ollut vuosikausia pyrkimyksenä päästä entistä suurempaan tuottavuuteen vähentämällä tarvittavan ohjelmakoodin määrää ja keskittämällä sitä niin, ettei yhden asian korjaus aiheuta muutoksia moneen paikkaan. LINQ To SQL pyrkii osaltaan nostamaan tätä tehokkuutta ja vähentämään tietokantakyselyissä tapahtuvia virheitä. Seuraava askel otetaan, kun LINQ To SQL:ää voidaan käyttää muidenkin
30 kuin Microsoft SQL Server -tietokantojen kanssa. Valtava määrä ohjelmistoyrityksiä ympäri maailmaa, kehittää ohjelmistoja Windows alustalle, joten LINQ ei varmasti tule katoamaan minnekään nyt ollaan vasta kehityksen alkumetreillä.
31 LÄHTEET Bernstein, L. 1997. Software Investment Strategy. Bell Labs Technical Journal, Summer 1997, 233-242. Kalima, L. 2004. SQL Server 2005 Sovelluskehitysseminaari. Viitattu 11.4.2008. http://seminaarit.codezone.fi/video/09122004/1/laurikalima.ppt Launiala, K. 2008. Linq to SQL käytännössä. Viitattu 11.4.2008. http://www.codezone.fi, Developer Days 2008 esitykset Codezonessa, LINQ to SQL käytännössä: käyttöönotto, sovellusrakenne ja työkalut. Pialorsi P. & Russo M. 2007. Introducing Microsoft Linq. Redmond: Microsoft Press.