[ wex-alpha @ 31.05.2010. 13:47 ] @
Kako da u LINQ-u napravim sljedeci query.

Imam tabelu sa 3 kolone. ID, ime i prezime;

Kako da dobijem ID kada vrsim pretragu po imenu?

Drugim rijecima, saljem string ime i zelim da mi LINQ vrati ID tog stringa.

Gledao sam na dosta mjesta, i evo metode koju sam napravio. Naravno da ne radi, ali vjerujem da sam blizu.

HELP.



METODA:
Code (csharp):


public string linkasmoj(string a)
        {
            Videotekabaza db = new Videotekabaza("Videotekabaza.sdf");

            var names = from Clanovi p in db.Clanovi
                        where p.Ime.Contains(a)
                        select p.Id;

            return a; // hocu da mi vrati id (svejedno je koji je tip, jer cu ga konvertovati po potrebi)
        }
 




POZIVANJE METODE
Code (csharp):


textBox2.Text =  linkasmoj(textBox1.Text);
 


[Ovu poruku je menjao mmix dana 31.05.2010. u 15:22 GMT+1]
[ mmix @ 31.05.2010. 14:14 ] @
pa dobro si uradio, samo sto ti je rezultat linqa int[] (ako je ID int), tj niz IDeva, treba da uzmes First() ili FirstOrDefault() da bi ti uradio TOP 1 u query-u.
[ wex-alpha @ 31.05.2010. 14:26 ] @
Sad sam primjetio da ce se messagebox aktivirati, jedino kada ime koje saljem pripada tom ID.

Molim te, mozel li malo pojasniti to sto si mi naveo? :)
[ wex-alpha @ 31.05.2010. 14:27 ] @
Malo sam preradio metodu, tako da rezultat salje u polje staticke klase.

Code (csharp):


            Videotekabaza db = new Videotekabaza("Videotekabaza.sdf");

            var names = from Clanovi p in db.Clanovi
                        where p.Ime.Contains(a)
                        select p.Id;

            foreach (int s in names)
            {
                   konekcija.linkanje = s; // Staticko polje klase konekcija
                   MessageBox.Show(Convert.ToString (s));
            }
 
[ mmix @ 31.05.2010. 14:34 ] @
A sta ti treba da vratis iz funkcije? jedan ID od prvog recorda cije ime je match ili SVE IDeve?

Ako ti treba prvi koristi names.First() on je tipa int kad se razvije query. First ce da pukne sa exception ako je LINQ rezulat prazan.

Code (csharp):

return (from Clanovi p in db.Clanovi
         where p.Ime.Contains(a)
         select p.Id).First().ToString();
 

[ wex-alpha @ 31.05.2010. 14:43 ] @
Ako u tabeli imam ime "vedran" i njegov je id 24. Treba mi taj broj 24 da vrati.

Na onaj nacin kako sam napisao, sam reaguje sa prvim unosom koji ima id 1.
[ wex-alpha @ 31.05.2010. 14:49 ] @
Sad sam probao tvoj primjer, i salje mi samo prvi unos. :(

[ mmix @ 31.05.2010. 14:54 ] @
Zakaci neki text writter za DataContext.Log (db.Log). Ovde imas primer kako da zakacis VS Deboug output na log: http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11
pa okaci SQL koji generise LINQ

inace, si siguran da ti a nije prazan string?

[ Shadowed @ 31.05.2010. 15:39 ] @
Izgleda da hoce sve ID-eve. Posto ih prikazuje u TextBox-u, moze da koristi Agregate na taj query, al' nikako da lepo naucim sintaksu istog.. A nemam sad vremena traziti..
[ mmix @ 31.05.2010. 16:03 ] @
Code (csharp):

Aggregate<int, string>("", (inp, n) => String.Format("{0}; {1}", n, inp));
 


prvo je pocetna vrednost, drugo je lambda (suma, sledecavrednost)

ovo se izvrsi kao

Code (csharp):

string s = default;
foreach (int x in source) s = lambda(s, x);
return s;
 
[ wex-alpha @ 31.05.2010. 18:40 ] @
Ne. string nije sigurno prazan. Sva polja su popunjena. Evo sta se desava.



ID ime prezime
1 wex alpha
2 vedran wex
3 john smith
4 john doe


CILJ
Moj cilj je ako posaljem string koji sadrzi vedran, zelim da mi se vrati ID, u ovom slucaju 2. Tip nije vazan, jer cu ga konvertovati svakako.



Sta se desava

Kada posaljem string vedran (ili bilo koji drugi string), nista ne dobijem natrag. Ako posaljem string wex (Id mu je 1), onda mi se vrati broj 1, zasto?
Evo koda koji to radi.

Code (csharp):


 public string linkanje(string a)

        {
           
            Videotekabaza db = new Videotekabaza("Videotekabaza.sdf");

            var names = from Clanovi p in db.Clanovi
                        where p.Ime.Contains(a)

                        select p.Id;
           
            foreach (int s in names)
            {
             
           konekcija.linkanje = s;
            MessageBox.Show(Convert.ToString (s)); //messagebox je samo provjera da vidim sta se desava.

           
            }
               
            return Convert.ToString( konekcija.linkanje);

       
        }
 



Kod koji mi je mmix predlozio par postova ranije:

Code (csharp):


return (from Clanovi p in db.Clanovi
         where p.Ime.Contains(a)
         select p.Id).First().ToString();
 



Ista se stvar desava.

dblm sam generisao sa SqlMetal (posto *.sdf nije podrzan u LINQ-u).


Nije samo da mi treba id, nego ce mi trebati i druga polja. Ali mislim da prvo skontam kako da dobijem vrijednost ID, pa cu za ostala polja lako.

Pravim kompleksne animacije, sa pojedinacnim poljima, zato mi treba kontrola nad svakim poljem pojedinacno.
Nakon pretrage, cini mi se da LINQ daje najbolju kontrolu nad poljma u bazi. Textbox (mozda cak i textblock) ce ionako biti hidden. A kasnije pomocu vrijednosti koje LINQ "strpa" u njih, tako cu trigerovati animacije.

Ili mozda grijesim?


Nisam jos probao ova zadnja dva prijedloga. Kasnije cu se pozabaviti s tim, pa mozda i uspijem.

[Ovu poruku je menjao wex-alpha dana 01.06.2010. u 09:09 GMT+1]
[ mmix @ 31.05.2010. 20:16 ] @
Nista ne mogu da ti odgovorim dok ne debagujes SQL izraz koji se izvrsava. Ignorisi poruke sa aggregate, to je offtopic. Dakle zakaci debug log i isprati koji SQL izraz je generisao LINQ i to okaci
[ wex-alpha @ 31.05.2010. 20:56 ] @
Vjerovatno ne koristim ispravno ovu klasu, jer nigdje mi nista ne ispisuje (ni Immidiate window niti debug output).

Razmisljao sam gdje da stavim db.Log = new DebuggerWriter(); i onda sam probao na ovaj nacin.


Code:

 foreach (int s in names)
            {

                konekcija.linkanje = s;
                MessageBox.Show(Convert.ToString(s));
                 db.Log = new DebuggerWriter();


            }



Izvinjavam se sto ne znam ovo koristiti :(
[ mmix @ 31.05.2010. 21:13 ] @
Dao sam ti link gore na primer kako se kaci LINQ na debug output

http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11
[ wex-alpha @ 31.05.2010. 21:26 ] @
Pa da, to i jesam probao.

Ubacio sam njegovu klasu u projekat.

i onda on kaze da koristim:

Code (csharp):

MyDataContext db = new MyDataContext();

db.Log = new DebuggerWriter();


 



Kako da deklarisem MydataContext MyDataContext db = new MyDataContext();. Pretpostavljam da je to moja baza, i onda u tom slucaju ide

Videotekabaza db = new Videotekabaza("Videotekabaza.sdf");

To vec imam. A gdje da stavim db.Log = new DebuggerWriter();... u foreach petlju?

Kao ovdje?:

Code (csharp):

  var names = from Clanovi p in db.Clanovi
                        where p.Ime.Contains(a)

                        select p.Id;

            foreach (int s in names)
            {

                konekcija.linkanje = s;
                MessageBox.Show(Convert.ToString(s));
                 
[b]db.Log = new DebuggerWriter();[/b]

            }

 


:(

[Ovu poruku je menjao wex-alpha dana 01.06.2010. u 09:08 GMT+1]
[ mmix @ 31.05.2010. 21:35 ] @
ma jok, samo jednom, nakon instanciranja

Code (csharp):

Videotekabaza db = new Videotekabaza("Videotekabaza.sdf");
db.Log = new DebuggerWriter();
...
 


Startujes program u debug modu i u VSu otvoris Debug Output prozor i sve ti se sliva tamo. stavi break point na foreach i kad udjes u foreach LINQ ce razviti i izvrsiti query, u tom trenutku ces u debug prozoru dobiti SQL izraz.
[ wex-alpha @ 01.06.2010. 07:08 ] @
Evo sta sam dobio:


Code:


names    {SELECT [t0].[id] FROM [clanovi] AS [t0] WHERE [t0].[ime] LIKE @p0
}    System.Linq.IQueryable<int> {System.Data.Linq.DataQuery<int>}

[ wex-alpha @ 01.06.2010. 08:05 ] @
Dok ne nadjem rjesenje za gore navedeni problem, nemam mira nego sam probao nesto drugo.
Konvertovao sam bazu u .xml fajl, te nad tim fajlom cu probati linq.

Evo XML Fajla:

Code (xml):

- <NewDataSet>
- <clanovi>
  <id>1</id>
  <ime>wex</ime>
  <prezime>alpha</prezime>
  </clanovi>
- <clanovi>
  <id>2</id>
  <ime>john</ime>
  <prezime>smith</prezime>
  </clanovi>
- <clanovi>
  <id>3</id>
  <ime>Hanah</ime>
  <prezime>Borg</prezime>
  </clanovi>
- <clanovi>
  <id>4</id>
  <ime>Edi</ime>
  <prezime>Papkanovic</prezime>
  </clanovi>
  </NewDataSet>

 



Evo LINQ-a, koji sam napravio. Richtextbox koristim tek tako da dobijem neki rezultat.

Code (csharp):


public string linkanje(string a)
        {

            XDocument xmlSource = XDocument.Load("myXmlDoc.xml");


            var Clanovi = from nesto in xmlSource.Descendants("clanovi")
           
                          where nesto.Element("ime").Equals(a)
                         
                          select new
                         
                          { ID = nesto.Element("Id")
                            //IME = nesto.Element("ime"),
                            //PREZIME = nesto.Element("prezime")                          
                          };

                          foreach (var proradivise in Clanovi)
                          {
                               richTextBox1.AppendText(proradivise.ID.ToString());
                           
                          }
return a;
 



Ovo nikako ne radi, koji mu je vrag? :(


PS
Radi sada. Napravio sam typo:
Bilo je
ID = nesto.Element("Id")
A treba da je
ID = nesto.Element("id")


Ali jos uvijek ostaje prvi problem. Mogu nastaviti sa radom koristeci i XML soluciju, ali me interesuje zasto prvi nacin ne radi?

[Ovu poruku je menjao wex-alpha dana 01.06.2010. u 09:47 GMT+1]
[ mmix @ 01.06.2010. 08:42 ] @
Imas ti neki drugi problem kod tebe, evo uradio sam isti primer kao ti i ja dobijam 2 za vedran

skini i pogledaj ovaj projekat. query je isti na kraju.
[ wex-alpha @ 01.06.2010. 09:03 ] @
Da, isti taj Code kod mene ne radi, t.j. uvijek vraca "0", osim ako nije prvo polje.

Na svu srecu nasao sam rjesenje preko xml-a.

mmix, mnogo ti hvala na trudu i vremenu i koji si ulozio :)