Linq päringukeel

From ICO wiki
Revision as of 15:32, 2 November 2010 by Htahis (talk | contribs) (→‎Eesmärk)
Jump to navigationJump to search

LINQ päringukeelega seotud tehnoloogiad

LINQ päringukeele kasutamine on võimalik tänu mitmetele uutele tehnoloogiatele C# programmeerimiskeeles. Järgnevalt lühike ülevaade mõningatest nendest tehnoloogiatest.

  • Muutujatüüp var
  • Objekti initsialiseerijad
  • Anonüümsed muutujatüübid
  • Laiendusmeetodid
  • Lambda avaldised

Muutujatüüp var

Muutujatüübiga var tähistatakse C# programmeerimiskeeles muutujaid, mille tüüp määratakse initsialiseerimise käigus. Samas on var tüübikindel, sest kui tüüp on korra määratud, siis edaspidi seda muuta ei ole võimalik.


Näide

 
string sona = "tere"; // luuakse string tüüpi muutuja sona
var sona2 = "tere";   // luuakse string tüüpi muutuja sona2
sona2 = 3                   // tekib viga, sest püütakse string tüüpi muutujale omistada int tüüpi väärtus

bjekti initsialiseerijad

Kui tavaliselt tuleb objekti loomise järel kõik vajalikud andmeväljad eraldi täita, siis objekti initsialiseerijad loovad võimaluse algväärtustada loomise käigus ka kõik vajalikud andmeväljad.


Näide

inime tonu = new inime(); // luuakse uus andmeobjekt tonu, mis on inime tüüpi
tonu.eesnimi = "jaan";       // väärtustatakse andmeväli eesnimi stringiga „jaan“
tonu.vanus = 19;                 // väärtustatakse andmeväli vanus int tüüpi väärtusega 19

inime tonu2 = new inime { eesnimi = "jaan", vanus = 19 }; // on samaväärne eelnevaga

Anonüümsed muutujatüübid

Anonüümsed muutujatüübid võimaldavad andmeobjekti tüübi luua selleks eelnevalt klassikirjeldust loomata.


Näide

var inime2 = new { eesnimi = "Heiki",  vanus = 28 }; // luuakse kahe andmeväljaga uus muutujatüüp
var jorss = new { vanus = 8, eesnimi = "Jaan" };  // luuakse kahe andmeväljaga uus muutujatüüp

Eelnevas näites toodud muutujatüübid on erinevad, sest nende andmeväljad on erinevas järjekorras (esimesel string ja int ning teisel int ja string).

Laiendusmeetodid

Laiendusmeetod on staatiline meetod, mis on väljakutsutav moel nagu see oleks konkreetse instantsi dünaamiline meetod. Võimalikuks teeb selle märksõna this meetodid parameetri ees. Kui luua uus klaas Laiendused ning sinna sisse meetod LoeSonadLauses, mis näib välja nii:

    public static class Laiendused
    {
        public static int LoeSonadLauses(this String lause)
        {
            return lause.Split(new char[] { ' ', ',', '.' }).Length;
        }
    }

siis tekib kõigile samas nimeruumis olevatele stringidele kasutatavaks meetod LoeSonadLauses. Kui on soov kasutada stringidel teistes nimeruumides ka seda laiendusmeetodit, siis tuleb importida see klass vastavasse nimeruumi (kasutades using konstruktsiooni). Kui kasutada System.Linq nimeruumi, siis tekib muutujatüüpidele, mis realiseerivad IEnumerable tüüpi liidese laiendusmeetodid GroupBy, OrderBy, Average jne.

Lambda avaldised

Lambda avaldised C# keeles võimaldavad luua lihtsaid tingimuslauseid ning omistamisi.


Näide

List<int> arvud = new List<int>(); // luuakse int tüüpi list
for (int i = 0; i < 500; i++)
    arvud.Add(i); // täidetakse list arvudega 0..500
var paaritud = arvud.FindAll(N => N%2 != 0); // valitakse ainult paaritud arvud

Järgnevalt mõned lambda avaldiste kasutamise näited:

Lambda avaldis Tulemus Vastuse tüüp x => x +1 Kui x = 1, siis tulemus on 2 int x => x == 5 Kui x = 5, siis vastus true, muul juhul false boolean x => x % 5 == 0 Kui x jagub viiega, siis true, muul juhul false boolean (x,y) => x+y x ja y summa int (x,y) => x== y Kui x ja y on võrdsed, siis true, muul juhul false boolean  

LINQ päringud

LINQ päringud sarnanevad mõnevõrra SQL keele päringutele, kuid samas on need päringud rohkem sarnased keele üldisele süntaksile.


Näide

// loome lihtsa arvude listi, mis sisaldab arve nullist kuni 499’ni
List<int> arvud = new List<int>(); // luuakse int tüüpi list
for (int i = 0; i < 500; i++)
    arvud.Add(i); // täidetakse list arvudega 0..500

// teeme päringu, mis valiks sajast suuremad arvud:
var paaritud2 = from x in arvud
       where x % 2 == 0
       select x;

Eesti keeles võiks öelda, et üldiselt on LINQ päringu süntaks on järgmine: võta midagi kusagilt suuremast kuhjast, vaata, kas sobib, kui sobib, siis pista teise kuhja. Sorteerimine LINQ pärnig võimaldab ka tulemuste sorteerimist mingisuguste omaduste järgi.


Näide

  // Leia inimesed kelle nime pikkus on suurem kolmest ja sorteeri need vanuse järgi
  var inimesed3 = from x in inimesed
        where x.eesnimi.Length > 3
        orderby x.vanus
        select x;

Samas on LINQ lauset võimalik kasutada ka ainult sorteerimiseks.


Näide

    // Leia inimesed ja sorteeri need vanuse järgi
    var inimesed3 = from x in inimesed
          orderby x.vanus
          select x;

Samuti on võimalik luua LINQ päring, kus sobivad elemendid sorteeritakse mintme erineva omaduse järgi ning kasutada vastupidist sorteerimisloogikat (alustades suurimast).

// Leia inimesed kelle nime pikkus on suurem kolmest ja sorteeri need vanuse ning nime järgi
//vastupidises järjekorras
var inimesed3 = from x in inimesed
     where x.eesnimi.Length > 3
     orderby x.vanus, x.eesnimi descending
     select x;

LINQ to XML

LINQ to XML tehnoloogia sisaldab hulka tehnoloogiaid, mis on mõeldud XML formaadis info ja failide loomiseks, töötlemiseks ning muutmiseks. LINQ to XML vahendid on koondatud System.Xml.Linq nimeruumi. System.Xml.Linq nimeruum sisaldab mitmete klasside kirjeldusi, peamised klassid ja nende omavahelised seosed on kirjeldatud alloleval joonisel


XDocument on andmetüüp, mis võimaldab mälus hoida koopiat XML dokumendist. XDocument võib sisaldada: XElement (juurelement, mida tohib olla ainult üks), Xdeclaration, XdocumentType ja XProcessingInstruction. XElement on andmetüüp, mis võimaldab mälus hoida koopiat XML elemendist. XDocument võib sisaldada: XElement (võib olla mitu), XComment, an XProcessingInstruction, XAttribute ja tekstilisi väärtuseid. XAttribute on andmetüüp, mis sisaldab nime ja väärtuse paari. Eelmainitud kolm andmetüüpi ongi põhilised, millega programmeerijal tuleb kokku puutuda. XML formaadis andmeid võib ette kujutada kui XElementidest koosnevat puud.

  XML objektide loomine XML objektidest kõige enam kasutatav on XElement. Uue XElemendi loomiseks saab kasutada XElemendi klassi konstruktoreid: XElement(XElement) Loob uue XElemendi olemasoleva XElemendi baasil XElement(XName) Loob uue XElemendi etteantud märgdendinimega XElement(XStreamingElement) Loob uue XElemendi olemasoleva XStreamingElement baasil XElement(XName, Object) Loob uue XElemendi etteantud märgdendinimega ning määrab elemendi sisuks etteanutd objekti XElement(XName, Object[]) Loob uue XElemendi etteantud märgdendinimega ning määrab elemendi sisuks etteanutd objektide massiivi

Vaatame kõige lihtsamat juhtu:

//Loome uue XElemendi märgendinimega inimene
            XElement inimene = new XElement("inimene");
            Console.WriteLine(inimene);
            // Väljund: <inimene />

Loome nüüd XML objekti, mis sisaldab ka infot:

//Loome uue XElemendi märgendinimega inimene, 
//mis sisaldab väärtust "Jaan"
            XElement inimene2 = new XElement("inimene", "Jaan");
            Console.WriteLine(inimene2);
            // Väljund: <inimene>Jaan</inimene>

Loome nüüd XML objekti, mis sisaldab teist XElementi: //Loome uue XElemendi märgendinimega inimene, //mis sisaldab teist XElementi

           XElement inimene3 = new XElement("inimene", 
               new XElement("nimi","Jaan"));
           Console.WriteLine(inimene3);
           // Väljund:
           //<inimene>
           //  <nimi>Jaan</nimi>
           //</inimene>

Loome nüüd XML objekti, mis sisaldab kahte XElementi ja atribuuti: //Loome uue XElemendi märgendinimega inimene, //mis sisaldab kahte XElementi ja atribuuti

           XElement inimene4 = new XElement("inimene",
               new XElement("eesNimi", "Jaan"),
               new XElement("pereNimi", "Igamees"),
               new XAttribute("id", 1));
           Console.WriteLine(inimene4);
           // Väljund:
           //<inimene id="1">
           //  <eesNimi>Jaan</eesNimi>
           //  <pereNimi>Igamees</pereNimi>
           //</inimene>

Eelnevaga samaväärne on järgnev näide: //Loome uue XElemendi märgendinimega inimene, //mis sisaldab kahte XElementi ja atribuuti

           XElement inimene5 = new XElement("inimene");
           inimene5.Add(new XElement("eesNimi", "Jaan"));
           inimene5.Add(new XElement("pereNimi", "Igamees"));
           inimene5.Add(new XAttribute("id", 1));
           Console.WriteLine(inimene5);
           // Väljund:
           //<inimene id="1">
           //  <eesNimi>Jaan</eesNimi>
           //  <pereNimi>Igamees</pereNimi>
           //</inimene>

  XML failidest lugemine ja nende muutmine XML failist info lugemiseks kasutame näitena Eesti Panga poolt väljastatavaid valuutakursse. Eesti Pank pakub XML formaadis valuuta päevakursse aadressil : http://www.eestipank.ee/dynamic/erp/erp_xml.jsp?day=1&month=10&year=2009&type=4&lang=et, kusjuures antud aadressil on päevakursid 1. oktoober 2009 seisuga. Kui on soov saada mõne muu päeva päevakursse, siis peaks muutma aadressis sisalduvat kuupäeva. XML formaadis andmete mällu lugemiseks saab kasutada XElement või XDocument klassi meetodit Load. Näide: //Loen Eesti panga poolt pakutavad päevakursid mällu

           XElement kursid =   XElement.Load(

"http://www.eestipank.ee/dynamic/erp/erp_xml.jsp?day=1&month=10&year=2009&type=4&lang=et");

           //Trükin saadud XML formaadis andmed konsooli
           Console.WriteLine(kursid);
           //

Kui andmed on mällu loetud, siis on võimalik nende andmetega teostada LINQ päringuid. Näide: //Teen päringu kurssidesse valides välja

           //"Body" nimelise elemendi alamelemendi "Currencies"
           // kõik alamelemendid
           var valuutaNimed = from x in kursid.Element("Body").Element("Currencies").Elements()
                              select x.Attribute("text").Value;
           foreach (var x in valuutaNimed)
               Console.WriteLine(x);

Samuti on siinkohal võimalik seada kitsendusi, nii on näiteks võimalik otsida üles valuutad, mis sisaldavad nimes „kroon“. Näide: //Teen päringu kurssidesse valides välja

           //"Body" nimelise elemendi alamelemendi "Currencies"
           // kõigi alamelementide atribuudi "text" väärtused, mis sisaldavad
           // "kroon"
           var kroonid = from x in kursid.Element("Body").Element("Currencies").Elements()
                         where x.Attribute("text").Value.Contains("kroon")
                         select x.Attribute("text").Value;
           foreach (var x in kroonid)
               Console.WriteLine(x);

Lisaks on alati võimalik kasutada sorteerimist: Näide: //Teen päringu kurssidesse valides välja

           //"Body" nimelise elemendi alamelemendi "Currencies"
           // kõigi alamelementide atribuudid "text", mis sisaldavad
           // "kroon" ja sorteerin need pikkuse järgi
           var kroonid = from x in kursid.Element("Body").Element("Currencies").Elements()
                         where x.Attribute("text").Value.Contains("kroon")
                         orderby x.Attribute("text").Value.Length
                         select x.Attribute("text");
           foreach (var x in kroonid)
               Console.WriteLine(x.Value);

Kui nüüd muuta mõnda päringuga saadud väärtust, näiteks asendada saadud kroonide väärtuses „kroon“ sõnaga „euro“ siis muutuvad ka nende elementdide ja atribuutide väärtused algses Xelemendis! Näide:

           // Asendan väärtuse "kroon" väärtusega "euro"
           foreach (var x in kroonid)
               x.Value = x.Value.Replace("kroon", "euro");
           //Trükin välja mälus oleva XElemendi "kursid"
           Console.WriteLine(kursid);

Muudetud XElement on lihtsalt salvestatav, selleks tuleb kasutada meetodit Save. NB! Kui anda meetodile ette lihtsalt failinimi, siis salvestatakse fail programmi töökataloogi Näide:

           //Salvestan XElement kursid faili nimega kursid_muudetud.xml
           kursid.Save("kursid_muudetud.xml");