[ theilusion @ 03.05.2016. 13:28 ] @
Interesuje me kako se ovi problemi rješavaju sa EF Database First pristupom.
Npr. Imam 3 ili više tabela koje su u relaciji i treba da čitam određene kolone iz sve tri tabele.
Moram da radim JOIN tabela. Rezultat je npr neka lista objekata koji pripadaju različitim klasama.
Sad kada bi ja to "bindovao" desilo bi mi se da imam "binding" na isti property 2 ili više puta,
jer npr imam property "Name" u dve tabele i treba da ih prikazem u rezultujucoj listi. Valjda sam
bio razumljiv s obzirom da sam naveo da podatke treba da citam iz vise tabela.
Da li se pravi neki "view" u bazi u tom slucaju ili to može da se reši voleo bih da me neko "prosvetli"
malo. Neki link dp primera bi takođe dobrodosao.
Hvala unapred.
[ Predrag Supurovic @ 03.05.2016. 20:06 ] @
Kada imas relaciju izmedju tabela u EF ces to dobiti kao vezu izmedju objekata. Osnovna tabel ace iamti propertui koji je tipa objekta druge tabele i sve podatke iz druge tabele ces imati u tom propertiju, kao poseban objekat (ili listu objekata ako se radi o M strani) tako da neces imati preklapanje sa imenima polja.

Primer:


OsobaEntity {
string ime;
string prezime;
MestoEntity mesto;
}


MestoEntity {
string naziv;
string postanski_broj;
}


[ theilusion @ 03.05.2016. 21:28 ] @
Mislim da nisam shvatio.
Kako je to moguce ako ja imam ovakve tabele:

Class Car{
int idcar,
string name,
string type
}

Class Driver{
int iddriver
string name,
string lastname,
string contact
}

Class CarDriver{
int idcar,
int iddriver
}

Treba mi "name" iz Car i "name" iz Driver. Ovo je samo onako primer napamet. Meni treba mnogo slozeniji upit iz vise tabela gde u najmanje 3 tabele imam isti naziv kolone, kasnije property-ja itd. Ako moze neki link gdje je ovo ilustrovano bio bih vam zahvalan. Hvala vam što se interesujete.
[ Predrag Supurovic @ 03.05.2016. 23:00 ] @
Neš to ti tu nije u redu.

Trebalo bi da bude

Class CarDriver{
Car car,
Driver driver
}
[ theilusion @ 04.05.2016. 06:07 ] @
Pa to su samo nazivi tabela u bazi.
EF ih preslika u klase po modelu DatabaseFirst.
Dakle ja imam bazu koju sam izmodelovao u jednom drugom softveru i samo sam u VisualStudiju
generisao EF model i to je to. Ne znam šta je uopšte bitno kako se zovu tabele ili klase.
[ Predrag Supurovic @ 04.05.2016. 09:52 ] @
Nije bitno kako se zovu, bitne su veze između njih.
U primeru koji sam ti dao nisu bitna imena polja nego njihovi tipovi.
[ theilusion @ 04.05.2016. 10:12 ] @
Ako imate link primera gde je nesto slicno ilustrovano bilo bi dobro.
Ovako ne mogu skapiram.Ili jednostavno da vam dam konkretan primer, imena tabela u bazi, kolone iz tih tabela koje mi trebaju,
da napravite upit i smestite rezultat u listu.
[ dusans @ 04.05.2016. 10:28 ] @
Možeš da napišeš klasu koja ima propertije koje vraća upit:

http://stackoverflow.com/a/18608759/461810
Code:

public class CarDriver
{
    public int CarID { get; set; }
    public string CarName { get; set; }
    public int DriverID { get; set; }
    public string DriverName { get; set; }

    public static List<CarDriver> LoadCarDrivers();
    {
        MyDataContext dbContext = new MyDataContext(connectionString);
        return dbContext.Database.SqlQuery<CarDriver>
               ("SELECT Car.ID as CarID, Car.Name AS CarName, Driver.ID as DriverID, Driver.Name AS DriverName FROM Car, Driver").ToList();
    }


Ili onako kako je Pedja napisao... ne znam šta je problem da binduješ na recimo item.car.name?
[ Predrag Supurovic @ 04.05.2016. 16:15 ] @
Hm, problem je što izgleda kada se rai Database First generisani Entity objekti ne sadrže veze, pa to mora naknadno da se doda. Zato je theilusion zbunjen ovim sto sam rekao jer on te veze u objektnom modelu nema.

theilusion, biće da ti ne gine da proučiš Code first, jer ćeš tako naučiti da sam napraviš veze između entiteta.


Dušane, ovo što si ti predložio će da radi, ali je u suprotnosti sa idejom korišćenja EntityFrameworka.
[ theilusion @ 04.05.2016. 21:36 ] @
Aha. Razmotricu ovaj primer od @dusans. Deluje mi ok.
Da li ja narusavam nesto ako generisem EF model po principu "databse first" a onda naknadno da malo "rucno popravim".
Jednostavno dodam ove veze koje mi trebaju da bih mogao da napravim upit. Dakle u fazi sam ucenja EF pa ne znam da li
postoji neki "custom" pristup pri generisanju EF modela.
[ Predrag Supurovic @ 05.05.2016. 06:21 ] @
Naravno da ne. To je tako i zamisljeno, database first mozes da uadis samo jednom, a posle kastomizujes.

Kad udjes u stos onda batalis database first i radis code first, jer ti to svakako ne gine, a bar imas punu kontrolu.
[ mmix @ 05.05.2016. 19:24 ] @
Database first radi veze ako tabele u bazi sadrze referencijalni integritet. Ako si radio database-first i prevukao table u dizajner i nemas relacije, onda ih nemas ni u bazi i treba da se vratis na taj posao ponovo. ne znam koji si alat koristio za dizajn baze, ali skoro svi za koje ja znam podrzavaju relacioni model.

Potpuno je pogresan pristup koristiti bazu sa nepovezanim tabelama i onda simulariti relacije na aplikativnom nivou, na stranu mogucnost da cela baza postane sje*ana, database engine nema pojma o vezama iz join-a i ne moze efikasno da optimizuje izvrsavanje. To je, sto bi rekli, fireable offense.

Ove vrste brljotina sa krpljenjem baze u kodu su inace razlog zasto mi ne dozvoljavamo code-first. Postoji razlog zasto se arhitektura baza ceni i placa.
[ theilusion @ 05.05.2016. 23:05 ] @
Hej ljudi hvala puno na savetima.
Cim stignem pisem detaljnije o bazi koju imam.
Sto se tice referencijalnog integriteta meni su sve "ON UPDATE" i "ON DELETE" akcije postavljene na "NO ACTION".
To se dobije po default-u kada se za modelovanje koristi Sybase PowerDesigner koji sam ja koristio.
[ mmix @ 06.05.2016. 00:05 ] @
A da ti nisi kod Perisica na FTNu?

Proveri malo model, akcija nije vazna za tvoj problem, prveri u samoj generisucioj skripti ili na samoj bazi da li uopste postoje foreign keys u tabelama. Ja iskreno ne podnosim organski PowerDesigner, mnogo je abstraktan, postoje mnogo bolja resenja ako si fokusiran na (T)SQL baze.
[ theilusion @ 07.05.2016. 17:46 ] @
Mali sam citao jos tema vezano za ovu moju problematiku i dosao sam do zakljucka da se mozda ne razumemo :)
Postavicu sliku dela modela koji sam generisao po DatabaseFirst konceptu konkretnog primera.
Napominjema da sam model lepo proverio, proverio ralacije, uocio strane kljuceve i reference.
Na modelu će se videti da imam i navigacione property-je.

Evo konkretnog primera:
Imam tabelu RequistionSparePart koja je u vezi sa tabelama Car i SparePartProperty, to se vidi sa slike. Treba mi upit koji ce mi puniti listu sa svim proeprty iz RequistionSparePart i treba mi property name iz Car kao i property name iz SparePartProperty. Koliko sam shvatio iz literature JOIN ne bih trebao ni da koristim i da bih problem mogao da resim preko ovih navigacionih property-ja. Ako treba postavicu i onaj deo gde se vide mapiranja.


[ mmix @ 08.05.2016. 21:01 ] @
Ok, sad se onda konacno razumemo. Kad radis LINQ zaboravi na join-e kad imas navigacione propertije.

Dakle, postoji vise nacina da dobijes to sto hoces. Koji ces primeniti zavisi od tvoje konkretne potrebe, ali da bi ti bilo jasnije o cemu pricam, pogledaj na netu

"Eager loading" "Lazy loading" i "Explicit loading" za EF.NET

poenta je da das hintove/instrukcije EF.NETu sta da ti preloaduje i onda pustis da EF.NET sam rascivija jedan ili selectova da ti vrati to sto hoces.
[ theilusion @ 08.05.2016. 22:46 ] @
Hvala na odgovoru pogledacu.
Jos kada bi neki link sa primerom gde je pokazano "bindovanje" datagrid-a koji treba da prikazem bilo bi sjajno.
U svakom slucaju hvala na smernicama googlacu.
[ djordjeno @ 09.05.2016. 09:11 ] @
Citat:
mmix: Ok, sad se onda konacno razumemo. Kad radis LINQ zaboravi na join-e kad imas navigacione propertije.

Dakle, postoji vise nacina da dobijes to sto hoces. Koji ces primeniti zavisi od tvoje konkretne potrebe, ali da bi ti bilo jasnije o cemu pricam, pogledaj na netu

"Eager loading" "Lazy loading" i "Explicit loading" za EF.NET

poenta je da das hintove/instrukcije EF.NETu sta da ti preloaduje i onda pustis da EF.NET sam rascivija jedan ili selectova da ti vrati to sto hoces.


Meni je u EF zasmetalo sledece a u vezi je se tim o cemu pricas:
EF postavi sve navigacione propertije koje pronadje u shemi baze podataka i za njih generise u modelu odgovarajuce veze.
Vrlo cest je slucaj da dosta od njih nisu potrebni ni za jedan upit u aplikaciji, jer jednostavno nema zahteva.
I recimo ako odstranite te veze iz EF dizajnera (delete na navigacioni property), svaki sledeci put kad se uradi update modela (npr doda se novo polje) te veze se opet pojave.
[ theilusion @ 09.05.2016. 13:06 ] @
Pa dobro. Verujem da kako vreme bude odmicalo da ce i EF biti "pametniji".
Međutim, to što ti kažeš, ako sam dobro razumeo, i nije neki nedostatak jer odakle
model zna kakve ćeš ti ti zahteve da praviš i mora na neki način da se osigura.
To mi nekako dođe kao kada modeluješ bazu pa "dumaš" hoće li tvoj koncept zadovoljiti
vezu 1:n ili da bi bio siguran, "pošto nisi siguran", ti staviš vezu m:n.

Da se vratim mom problemu, našao sam dosta prepiske na ovu temu što mi je preporučio
& mmix, međutim nisam našao ništa konkretno kako da ovo iskoristim za moju WPF aplikaciju,
tačnije kako da nidujem moja polja u datagrid.
Evo konkretno za ove 3 tabele moj datagrid bi trebao da izgleda ovako:

Code:

<DataGrid Name="ListReq" AutoGenerateColumns="False" IsReadOnly="True">
       <DataGrid.Columns>
               <DataGridTextColumn  Header="Datum zahteva" />  //RequistionSparePart
               <DataGridTextColumn  Header="Datum izdavanja" />  //RequistionSparePart
               <DataGridTextColumn  Header="Br. zahteva" />  //RequistionSparePart
               <DataGridTextColumn  Header="Trebovana količina" />  //RequistionSparePart
               <DataGridTextColumn  Header="Izdata količina" />  //RequistionSparePart
               <DataGridTextColumn  Header="Naziv materijala" />  //SparePartProperty
               <DataGridTextColumn  Header="SAP broj" />   //SparePartProperty
               <DataGridTextColumn  Header="Ime vozila" />  //Car
               <DataGridTextColumn  Header="Broj motora vozila" />  //Car
      </DataGrid.Columns>
</DataGrid>


Iza svakog taga sam stavio koje bolje iz koje tabele iz baze bi tu trebalo da se binduje.
Da li ću ja objekte iz mog upita da smeštam u neku listu ili pravim neki datatable.
Gotovo sve primere koje sam našao objašnjeni su na konzolnoj aplikaciji. Koliko sam shvatio
ja bih za ovaj moj problem trebao da koristim "Eager loading".

P.S. Srećan dan pobede nad fašizmom :)
[ dusans @ 09.05.2016. 13:18 ] @
Izvučeš RequistionSparePart u neku listu i dalje binduješ ovako:

Code:

Binding="{Binding dateOfRequest}"
...

Binding="{Binding SparePartProperty.name}"
...

Binding="{Binding Car.name}"
...


Eager loading koristiš da ti ne bi za svaki rekord skakao u bazu kad treba da učita recimo Car.
[ theilusion @ 09.05.2016. 13:47 ] @
Aha, sad mi je malo jasnije.
Ajde pre nego što probam da vidim rezulatat u aplikaciji da li bi onda moj upit trebao da izgleda nešto ovako (pišem onako napamet):

Code:
using (MyEntityModel mod = new MyEntityModel ())
{
  var result = mod.RequisitionSparePart.Include("Car").Include("SparePartProperty").ToList();
        foreach (RequisitionSparePart part in result)
        {
           RequisitionSparePartList.Add(part);
        }
}


Ne vidim kako bih drugacije dosao do SparePartProperty.name i Car.name
[ theilusion @ 09.05.2016. 20:24 ] @
Ja sam ovo probao i radi. Upit koji sam tu postavio zavrsava posao.
Sledece sto su probati da uradim je da izmenim ove podatke.
Iskoristicu INotifyPropertyChanged. Nadam se da sam na pravom putu
da savladam EF. Hvala jos jednom svima koji pomazu.
[ dejanet @ 09.05.2016. 20:39 ] @
Kako si krenuo ucitavaces celu bazu za 1 result set.
[ theilusion @ 09.05.2016. 23:12 ] @
Pa vidi, meni treba većina tih podataka iz sve tri tabele.
Predloži kako da optimizujem upit. I hvala što se interesujes.
[ mmix @ 10.05.2016. 13:46 ] @
Citat:
djordjeno:
Meni je u EF zasmetalo sledece a u vezi je se tim o cemu pricas:
EF postavi sve navigacione propertije koje pronadje u shemi baze podataka i za njih generise u modelu odgovarajuce veze.
Vrlo cest je slucaj da dosta od njih nisu potrebni ni za jedan upit u aplikaciji, jer jednostavno nema zahteva.
I recimo ako odstranite te veze iz EF dizajnera (delete na navigacioni property), svaki sledeci put kad se uradi update modela (npr doda se novo polje) te veze se opet pojave.


Memorija je jeftina, a navigacioni property leba ne jede ako ga ne koristis. Model pretpostavlja da ako si stavio dve uvezane tabele na model, da ti treba i njihova relacija. Ja ne verujem da ce se ovo ikad menjati.


Citat:
theilusion:
Aha, sad mi je malo jasnije.
Ajde pre nego što probam da vidim rezulatat u aplikaciji da li bi onda moj upit trebao da izgleda nešto ovako (pišem onako napamet):

Code:
using (MyEntityModel mod = new MyEntityModel ())
{
  var result = mod.RequisitionSparePart.Include("Car").Include("SparePartProperty").ToList();
        foreach (RequisitionSparePart part in result)
        {
           RequisitionSparePartList.Add(part);
        }
}


Ne vidim kako bih drugacije dosao do SparePartProperty.name i Car.name


Ok, mozes da flatujes objektni model u XxY recordset format (vidi pp). Drugo, zasto prelopatavas podatke iz liste u observable? To ti je najgore moguce resenje (svaki Add ce da uradi refresh svih vizuelnih drva vezanih za kolekciju).
Ili kreiraj novi observable pa koristi INotifyPropeortyChanged da javis UI da je instnca kolekcije promenjena
Ili proguglaj "AddRange" ekstenziju za observable collection koji ti sprecava refresh dok se cela lista ne pretaba.