[ patak_daca @ 24.12.2014. 06:28 ] @
Pozdrav!

Kako da postojeći linq upit rasparčam u delove ( select , groupby, order) i spajam ih po izboru ( bez groupby ili sa groupby ) ?

var query1 = from qin baza_kon.Tabela

where a.Aktivan == 1

group a by a.kolona1 into newGroup

orderby newGroup.Key

select newGroup;



ako neko zna molim za pomoć...

Hvala!!

Patak
[ Shadowed @ 24.12.2014. 08:33 ] @
Code:

var where_part = baza_kon.Tabela.Where(a => a.Aktivane == 1);
var group_part = where_part.GroupBy(a => a.kolona1);
var orderby_part = group_part.OrderBy(a => a.Key);



Proveri malo, mozda sam negde omasio, kucao sam napamet, bez VS-a.
Stvar je u tome da se svi ti LINQ upiti konvertuju u pozive funkcijama koje mozes i sam koristiti sto je i prakticnije za ovo sto ti treba.
[ patak_daca @ 24.12.2014. 08:40 ] @
Pozdrav!

Odlično! Hvala puno!

Patak
[ patak_daca @ 24.12.2014. 09:28 ] @
Ako su podaci grupisani da li moram praviti novi View u odnosu ako nisu ?
Da li postoji neko eleganto rešenje ?
[ patak_daca @ 25.12.2014. 09:42 ] @
Da li neko ima predlog kako uraditi View ako postoji mogućnost da podaci budu grupisani i ne moraju biti ?

Kada u View bude
@model List<IGrouping< string , Model>> onda su grupisani podaci

a postoji mogućnost da korisnik ne želi da gupiše podatke.

Ako neko ima predlog ?

Hvala!

Poz

[ mmix @ 25.12.2014. 09:50 ] @
Uvek mozes da grupises sve podatke u jednu grupu, tako ne moras da menjas model type u View-u.

[ patak_daca @ 25.12.2014. 10:00 ] @
Kada posle svih delova i spajanja linq upita....dobijem query2

var keyEmplist = (from IGrouping<string,Model> dat in query2 select dat).ToList();


return View("FormResults", keyEmplist);


kako da ih gupišem u jednu gupu ?

Hvala!


[ mmix @ 25.12.2014. 10:26 ] @
Pa ti si tu vec grupisao podatke. Imas sigurno neki if/then/else branch koji ti generise LINQ koji nije grupisan. Njega grupises u isti tip kao i ovaj linq.
[ patak_daca @ 25.12.2014. 11:49 ] @
Uradio sa grupisanje podataka...radi odlično...

ali kada šaljem u View prijavi grešku...jer očekuje string a ja grupisao po int ( grupisano po Id iz tabele )
onda moram da promenim i u View u int..

var keyEmplist = (from IGrouping<string, Vezbe_sa_DIV.EF.Tiket> dat in query2 select dat).ToList();

onda View zavisi on kontrolera i kojeg šaljem podatke...ili ne ?
[ pl4stik @ 25.12.2014. 12:18 ] @
Probaj da stavis object kao parametar koji ocekujes umesto string pa proveravaj jel string ili int ili...
[ patak_daca @ 25.12.2014. 12:45 ] @
Uspeo sam da rešim...uvek ću da grupišem po int (id, id_mesta, id_posla ...)
...ali samo još ovo

kako mmix piše

Citat:
mmix: Pa ti si tu vec grupisao podatke. Imas sigurno neki if/then/else branch koji ti generise LINQ koji nije grupisan. Njega grupises u isti tip kao i ovaj linq.


vrati mi se samo Key vrednost a meni trebaju i ostale vrednosti iz te tabele koju sam grupisao po Id...

molim za pomoć.

[ patak_daca @ 26.12.2014. 10:00 ] @
Zašto ako posle grupisanja podataka uradim orderby

var group_part = where.GroupBy(a => a.Gradovi.Id_mesto);

orderby_part = group_part.Select(o => new { id = o.Key, NazivGrada = o.OrderBy(c => c.StatusTiketa.NazivStatusa) });


dobijam grešku u delu

var keyEmplist = (from IGrouping<int, Vezbe_sa_DIV.EF.Tiket> dat in query2 select dat).ToList();

greška je

Unable to cast the type 'Anonymous type' to type 'System.Linq.IGrouping`2'. LINQ to Entities only supports casting EDM primitive or enumeration types.

??
[ mmix @ 26.12.2014. 10:14 ] @
Pa rasturio si grupisanje sa selectom, rezultat selecta nije IGrouping vec tvoj anonimni objekat.

Imaj u vidu da je C# strong-typed, cak iako se tvoj objekat slaze po imenima polja ne znaci da je ista klasa.
[ patak_daca @ 26.12.2014. 10:17 ] @
uf...pa kako da uradim orderby po nekoj drugom drugom polju osim Key-a ?

molim za pomoć...
[ mmix @ 26.12.2014. 11:15 ] @
Vrlo slabo mozemo da ti pomognemo jer kacis samo nepovezane delove koda.

Al btw ovo je potpuno besmisleno:

(from IGrouping<int, Vezbe_sa_DIV.EF.Tiket> dat in query2 select dat).ToList();


dobijas isto i sa dat.ToList()

[ patak_daca @ 26.12.2014. 11:47 ] @
ok...evo koda...

Code (csharp):

var where = baza_kon.Tikets.Where(a => a.Aktivan == 1);

 if (!String.IsNullOrEmpty(status))
            {

                if (status != "sve")
                {
                    where = where.Where(a => a.StatusTiketa.NazivStatusa == status);

                }
                         
               
            }

            System.Linq.IQueryable orderby_part = null;

            if (!String.IsNullOrEmpty(Grupisi))
            {
                ViewBag.grupisi = "1";

                if (Grupisi == "ms.NazivGrada")
                {
                 
                    var group_part = where.GroupBy(a => a.Gradovi.Id_mesto);

                    orderby_part = group_part.OrderBy(a => a.Key);

                                     
                }

                if (Grupisi == "vr.NazivVrsteRada")
                {
                    var group_part = where.GroupBy(a => a.VrsteRadova.Id_vrste_rada);

                    orderby_part = group_part.OrderBy(a => a.Key);

                }


            }

            else

            {

                ViewBag.grupisi = "0";

                var group_part = where.GroupBy(a => a.Id_tiket);

                orderby_part = group_part.OrderBy(a => a.Key);

               
            }


           var query2 = orderby_part;
           
           
            var keyEmplist = (from IGrouping<int, Vezbe_sa_DIV.EF.Tiket> dat in query2  select dat ).ToList();


            return View("FormResults", keyEmplist);

}


}
 


U bilo kom groupb pokušavam da kreiram orderby po nekoj drugoj koloni osim Key

možda je malo nepregledno kodirano ..ali radi..

ako neko ima predlog...

Molim pomoć...

[Ovu poruku je menjao mmix dana 26.12.2014. u 15:15 GMT+1]
[ mmix @ 26.12.2014. 14:10 ] @
Postoji i elegantniji nacin za sve ovo...

Ajd pogledacu danas ako uhvatim malo vremena da ti dam par saveta.


[ patak_daca @ 26.12.2014. 14:39 ] @
Odlično!! Hvala puno!!
[ mmix @ 26.12.2014. 21:05 ] @
Code (csharp):


     var queryX = from a in baza_kon.Tickets
                          where a.Aktivan == 1
                          select a;

     Expression<Func<Ticket, bool>> statusFilter = a => true;
     if (!String.IsNullOrEmpty(status)) statusFilter = a => a.StatusTiketa.NazivStatusa == status;

     queryX = queryX.Where(statusFilter);
     
     ViewBag.grupisi = "0";
     Expression<Func<Ticket, int>> groupFilter = a => a.Id_tiket;
     if (!String.IsNullOrEmpty(Grupisi))
     {
        ViewBag.grupisi = "1";
          if (Grupisi == "ms.NazivGrada") groupFilter = a => a.Gradovi.Id_mesto;
          if (Grupisi == "vr.NazivVrsteRada") groupFilter = a => a.VrsteRadova.Id_vrste_rada;
     }
     
     var keyEmplist = queryX.GroupBy(groupFilter).OrderBy(a => a.Key);

     return View("FormResults", keyEmplist);
 


probunari malo po ovome pa pitaj sta ti nije jasno.

[ patak_daca @ 26.12.2014. 21:15 ] @
Svaka čast! Nemam šta da kažem!

Jedino me brine kako da napravim order , ali po nekoj drugoj koloni osim Key -a kada grupišem...

Poz
[ mmix @ 26.12.2014. 22:02 ] @
Rezultat GroupBy nisu kolone. Prva stvar koju moras da razlucis je da LINQ ne koristi flat model kao sto to radi SQL, koristi objektni model, rezultat svih operaciju nisu redovi sa kolonama vec liste objekata, gde se samo finalni objekti mogu posmatrati kao flat liste polja/kolona (mada ni to nije tacno jer svaka "kolona" moze biti bilo sta, objeakt ili cak nova lista). Samim tim rezultat group by operacije je lista (IOrderedQueryable) group objekata (IGrouping) koji poseduju kljuc (int32) i listu polaznih objekata (Ticket) za specificnu vrednost kljuca, npr:



Ako hoces da lista ticketa unutar grupe bude sortirana, onda primenis sort na listu od koje se gradi grupa (na queryX), jer su sve iterativne LINQ operacije, kao sto je groupby, linearne (idu od pocetka seta ka kraju)


Btw, ako te interesuje kako sam dobio gornju sliku, google LinqPad i skini ga, koristice ti.
[ mmix @ 26.12.2014. 22:26 ] @
Drugi savet koji imam da ti dam je da ne preterujes mnogo Trebalo bi da gledas kako da minimizujes broj upita u bazu, to je nesto sto mnogo ljudi zaboravi koristeci LINQ. Gornji kod, i moj i tvoj, ce izazvaati vise upita u bazu u zavisnosti od toga koje grupisanje se koristi. Mnogo bolja opcija bi ti bila (posto ionako skidas sve aktivne tikete), da ih sve ucitas u listu (resolvujes iz Linq2SQL/EF u cisti Linq) i da onda manipulises u lokalnoj memoriji. Ovaj kod bi onda bio:

Code (csharp):

     var queryX = from a in baza_kon.Tickets
                          where a.Aktivan == 1
                          select a;

     Expression<Func<Ticket, bool>> statusFilter = a => true;
     if (!String.IsNullOrEmpty(status)) statusFilter = a => a.StatusTiketa.NazivStatusa == status;

     var listX = queryX.Where(statusFilter).ToList();
     listX.Dump();
     
     ViewBag.grupisi = "0";
     Func<Ticket, int> groupFilter = a => a.Id_tiket;
     if (!String.IsNullOrEmpty(Grupisi))
     {
        ViewBag.grupisi = "1";
          if (Grupisi == "ms.NazivGrada") groupFilter = a => a.Id_mesto;
          if (Grupisi == "vr.NazivVrsteRada") groupFilter = a => a.Id_vrste_rada;
     }
     
     var keyEmplist = listX.GroupBy(groupFilter).OrderBy(a => a.Key);
 


Primeti par razlika:
- uveli smo listX, on vise nije IQueryable<Ticket> vec List<Ticket> zbog ToList()
- kad pozovemo to ToList(), Linq query se izvrsi na DB serveru i dobijamo podatke u memoriji
- posto vise Linq2SQL/EF ne mora da prevodi query u SQL, nema potrebe ni da koristimo Expression<Func<>> delegat, dovoljno je da koristimo Func<> jer ce se delegat izvrsaavti u lokalnoj memoriji nad lokalnim podacima.
- posto je foreign key isti u tickets i u parent objektima, vrse ne radimo grouping po parent objektu da bi izbegli call-back u bazu
- rezultat sada vise nije IOrderedQueryable, vec IOrderedEnumerable, ali sa funkcionalnog stanovista oni su identicni za tvoju upotrebu:




PS: Otvorio sam jednu vrednost u jednom polju, cisto da vidis da "kolona" u stvari nije jednostavan tip, vec drugi objekat.


[Ovu poruku je menjao mmix dana 26.12.2014. u 23:46 GMT+1]
[ patak_daca @ 27.12.2014. 07:51 ] @
mmix hvala ti puno !!! Ovo što si napisao je zapravo uputsvto kako raditi sa LInq.
Ovo će svakome da koristi ko se time bavi.
Potrudiću se da sve to razumem i primenim u rešavanju problema..
Poz
[ patak_daca @ 27.12.2014. 08:32 ] @
Kada primenim ovaj kod u LinaPad-u

from a in Tikets
orderby a.StatusTiketas.NazivStatusa descending
group a by a.Gradovis.NazivGrada into newGroup
select newGroup

radi upravo ovo što hoću..sortira mi grupu po NazivuStatusa

ali kada primenim na code u C# ( onaj što si mi prepravio ili na onaj moj ne radi.....)

molim te za pomoć...
[ mmix @ 27.12.2014. 10:51 ] @
U LinqPad-u, promeni sistem rada sa "C# Expression" na "C# statements" i onda mozes da pises regularan visekomandni c# kod. Da bi neki objekat bacio na izlaz, pozivas ekstenziju Dump() (npr keyEmplist.Dump(); )
[ patak_daca @ 27.12.2014. 11:18 ] @
U linqpad-u ubacim code

var queryX = from a in Tikets
orderby a.Id_statusa_tiketa ascending
where a.Aktivan == 1

select a ;

queryX = queryX.Where( a => true);

var keyEmplist = queryX.GroupBy(a=>a.VrsteRadovas.Id_vrste_rada).OrderBy(a => a.Key).ToList();

keyEmplist.Dump();

radi odlično,

a isti tak code u C# ne radi...naime

kada idem korak po korak u C# sve do grupisanja drži orderby a kada se uradi groupby order se vrati na stari...
[ mmix @ 27.12.2014. 11:37 ] @
ovo zvuci kao problem sa SQLom, tj prevodjenu expressiona.
kakav SQL dobijes ?

I probaj sa onom forom sa queryY, da prebacis podatke u memoriju i grupises na klijentu.
[ patak_daca @ 27.12.2014. 11:38 ] @
Izgleda nešto nije u redu..

čitam ovo http://stackoverflow.com/quest...erby-dismissed-order-operation...
[ mmix @ 27.12.2014. 11:43 ] @
Da, to objasnjava.

Because it's Enumerable.GroupBy that preserves order. No such promise is made for Queryable.GroupBy.
From the documentation of the former:
The IGrouping(Of TKey, TElement) objects are yielded in an order based on order of the elements in source that produced the first key of each IGrouping(Of TKey, TElement). Elements in a grouping are yielded in the order they appear in source.
[ patak_daca @ 27.12.2014. 11:48 ] @
Na drugi način radi odlično...orderby ostaje nepromenjen

samo što prijavi grešku

The model item passed into the dictionary is of type 'System.Linq.OrderedEnumerable`2[System.Linq.IGrouping`2[System.Int32,Vezbe_sa_DIV.EF.Tiket],System.Int32]', but this dictionary requires a model item of type 'System.Collections.Generic.List`1[System.Linq.IGrouping`2[System.Int32,Vezbe_sa_DIV.EF.Tiket]]'.

molim te pomozi...

[ mmix @ 27.12.2014. 11:53 ] @
Cini i se da pokusavas da reusujes varijablu List tipa da u nju smestis IOrderedEnumerable rezultat iz OrderBy().

To ne moze Iako je nesto deklarisano kao var ono i dalje ima strong type. Ili pozov ToList() ili koristi drugi var
[ patak_daca @ 27.12.2014. 11:55 ] @
BRAVO mmix !! Odlično radi!! Hvala!!!!!