Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Entity Framework, Combobox DataBinding po kompozitnom kljucu...

[es] :: .NET :: Entity Framework, Combobox DataBinding po kompozitnom kljucu...

[ Pregleda: 1878 | Odgovora: 9 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

Mikelly

Član broj: 16730
Poruke: 389
*.49.crnagora.net.



Profil

icon Entity Framework, Combobox DataBinding po kompozitnom kljucu...02.03.2011. u 19:45 - pre 160 meseci
Imam dva entiteta u EF modelu koji su vezani po kompozitnom kljucu:
1. Biracka_Mjesta (FK_Grad, Broj_Birackog_Mjesta, Code_Birackog_Mjesta) i
2. Clanovi (Sifra_Opstine, Broj_Birackog_Mjesta, Sifra_Birackog_Mjesta).

Evo kako sam podesio databinding za combobox koji vuce podatke iz EntitySeta BirackaMjesta za izbor birackog mjesta kome jedan clan pripada:
Code:

<ComboBox Name="cmbBirackoMjesto1" DisplayMemberPath="Naziv_Birackog_Mjesta" SelectedValuePath="/" SelectedItem="{Binding Biracko_Mjesto}"/>

Znaci, vezem ga ne za jedno polje u entitetu, vec za EntityReference (non stop imam zelju da napisem tabela, umjesto entitet). U prevodu, ono biracko mjesto koje izaberem (SelectedValuePath="/") smjesti mi u EntityReference Biracko_Mjesto entiteta Clanovi. EntityReference Biracko_Mjesto je povezan sa entitetom Biracka_Mjesta kompozitnim kljucem po 3 gornja polja.

ItemsSource za combobox podesavam u kodu:
Code:

CollectionViewSource cvsBirackaMjesta = new CollectionViewSource();
cvsBirackaMjesta.Source = entities.lista_birackih_mjesta;
this.cmbBirackoMjesto1.ItemsSource = cvsBirackaMjesta.View;


Na pocetku mi je izgledalo da ce ovo da radi. Jer, kada unosim novog clana, i izaberem mu biracko mjesto, sve radi ok, update u bazu takodje, sve je kako treba.

Problem nastaje je kada je Clan vec u Unchanged stanju, tj. kada ga dovucem iz baze, a zelim mu promijeniti biracko mjesto. Kako izaberem neku drugu vrijednost iz combo boxa, evo koji exception dobijem:
Code:

A referential integrity constraint violation occurred: A primary key property that is a part of referential integrity constraint 
cannot be changed when the dependent object is Unchanged unless it is being set to the association's principal object. 
The principal object must be tracked and not marked for deletion.


U aplikaciji imam jos par situacija kada clanovima biram neke druge karakteristike (Struku, Pol, Bracno stanje, itd) ali su to sve veze po jednom polju (surogat kljucevi) i u tim situacijama nemam nikakvih problema.

Googlanjem sam dosao samo do predloga da modifikujem model tako da napravim relaciju samo po jednom polju, sto generalno nije losa ideja jer ja mnogo volim surogat kljuceve, ali u ovom slucaju nemam izbora, jer dobijam podatke sa strane, i moram postovat njihove kljuceve.

Znam da je ovo nova tehnologija, ali mozda neko ima rjesenje, ili ideju, puno bi mi pomoglo.

Pozdrav.
 
Odgovor na temu

Boris B.
Ljubljana

Član broj: 213615
Poruke: 286
*.evj-kabel.net.



+14 Profil

icon Re: Entity Framework, Combobox DataBinding po kompozitnom kljucu...04.03.2011. u 19:58 - pre 160 meseci
Polja koja su deo EntityKey strukture ne mozes da menjas direktno zbog nacina na koji EF trekuje objekte.
Moraces da koristis surogat kljuceve i iskreno ne vidim nikakav problem cak i ako dobijas podatke "sa strane", postavi samo u bazi Unique Key constraint na kombinaciju polja koja cini originalni kljuc, da bi baza bila konzistentna za uvoz/izvoz za te "sa strane".

Drugi nacin je da koristis neki svoj ViewModel a ne da bindujes na data objekte direktno, onda kada postujes ViewModel rekreiras entitete ako se promenio neki element primarnog kljuca, mada je to glavobolja i ne preporucujem.
if it walks like a duck and quacks like a duck, it could be a dragon doing a duck
impersonation.
 
Odgovor na temu

Mikelly

Član broj: 16730
Poruke: 389
77.222.27.*



Profil

icon Re: Entity Framework, Combobox DataBinding po kompozitnom kljucu...05.03.2011. u 13:46 - pre 159 meseci
Ok, ja sam vec krenuo u tom pravcu, mada mi ipak neke stvari nisu najjasnije.

Tvoj odgovor zvuci skroz logicno, ali ja i ne pokusavam da direktno mijenjam polja koja su dio EntityKey-a.

Ja bindujem item na item (izabrano biracko mjesto na EntityReference biracko_mjesto clana), pa prepustam EF-u da odradi popunjavanje polja kako on misli da treba.

I na kraju, da li ovo sve znaci da je u EF-u nemoguce promijeniti strani kljuc, ukoliko je veza kompozitna?
 
Odgovor na temu

Boris B.
Ljubljana

Član broj: 213615
Poruke: 286
*.evj-kabel.net.



+14 Profil

icon Re: Entity Framework, Combobox DataBinding po kompozitnom kljucu...05.03.2011. u 23:19 - pre 159 meseci
Prvo koji EF koristis, prvi ili drugi (EF4)? Prvi nije dozvoljavao da menjas polja koja su deo FK kljuca, drugi je svestan foreign kljuceva i radi 100%, koristim svaki dan.

Citat:
Mikelly: I na kraju, da li ovo sve znaci da je u EF-u nemoguce promijeniti strani kljuc, ukoliko je veza kompozitna?

Nemoguce je, ukoliko je neki od clanova kompozitnog foreign kljuca ujedno i deo primary kljuca tabele/entiteta, ne znam da li je to kod tebe slucaj ali pretpostavljam da jeste, s obzirom na gresku koju si napisao da dobijas:
Citat:
Mikelly
Code:

A referential integrity constraint violation occurred: A primary key property that is a part of referential integrity constraint 
cannot be changed when the dependent object is Unchanged unless it is being set to the association's principal object. 
The principal object must be tracked and not marked for deletion.

if it walks like a duck and quacks like a duck, it could be a dragon doing a duck
impersonation.
 
Odgovor na temu

Mikelly

Član broj: 16730
Poruke: 389
77.222.27.*



Profil

icon Re: Entity Framework, Combobox DataBinding po kompozitnom kljucu...06.03.2011. u 09:56 - pre 159 meseci
Da, upravo je to slucaj, tri polja stranog kljuca su dio primarnog kljuca foreign tabele. Znaci da zaboravim kompozitne kljuceve. Nikada ih vala nijesam ni volio.


Pitao bih te jos nesto, tice se validacije u EF. Sta ti koristis za validaciju? Exception-e, IDataErrorInfo ili ValidationRules?

Koliko god se mucio, nema sanse da mogu da uhvatim Exception koji bacim u partial classi entiteta. Dzabe stavljam ValidatesOnExceptions=True u Binding MarkupExtension-u.

ValidationRules mi se cine mnogo mocni, ali se tada validacija vrsi na nivou kontrola, plus imam problema da ukapiram kako tacno rade, pogotovo ako hocu da vrsim validaciju preko DataGrid-a.

Ostaje mi IDataErrorInfo, za sad mi se cini ok, mada ga tek upoznajem.

Pa bih te molio za savjet.

Jos jedna stvar. Ponekad, kada imam setovan error na entitetu, bilo preko IDataErrorInfo vracanjem stringa greske u Error get-eru, bilo vracanjem false ValidationResult-a u ValidationRule-u, citava ItemsControl kontrola (DataGrid konkretno) mi je disable-ovana sve dok ne ispravim gresku. To je ponasanje kakvo zelim, ali ponekad to nije slucaj, a ja ne mogu da uhvatim pravilo po kome se to desava (ne desava). Pa ako se te tebi kad desilo...


Pozdrav i hvala.
 
Odgovor na temu

Boris B.
Ljubljana

Član broj: 213615
Poruke: 286
*.evj-kabel.net.



+14 Profil

icon Re: Entity Framework, Combobox DataBinding po kompozitnom kljucu...06.03.2011. u 13:13 - pre 159 meseci
Za validaciju ja koristim neki svoj ValidatorResult koji sadrzi
Code (csharp):

public class ValidatorResult
{
    EntityObject Entity { get; private set; } // Koji entitet je izazvao gresku
    DataError Error { get; private set; } // Strongly-typed greska
}

public class FieldValidatorResult : ValidatorResult
{
    string FieldName { get; private set; } // Polje kod koga je doslo do greske
}
 


Zatim imam neki ValidatorResult Validate(ObjectContext context) koji mi validira ceo kontekst, tako sto za sve entitete u kontekstu koje implementiraju IValidationProvider zove IValidationProvider.Validate()
Code (csharp):

public interface IValidationProvider
{
    public ValidatorResult Validate(ObjectContext context)
}

...

partial class Osoba : IValidationProvider
{
    public ValidatorResult Validate(ObjectContext context)
    {
        if (string.IsNullOrWhitespace(Ime))
            return new FieldValidatorResult { Entity = this, Error = DataErrors.RequiredField, FieldName = "Ime" };
        if (this.SamoJedan && context.Osoba.Count(o => (o.Uid != this.Uid) && (o.SamoJedan)) > 0)
            return new ValidatorResult { Entity = this, Error = DataErrors.SamoJednaOsoba };
        ... // Ostale provere
        return null;
    }
}

 


Prednost ovoga je sto je kontekst validacije ceo UnitOfWork a ne jedno polje ili jedan entitet, tj. mozes da validiras ne samo da li je polje ili entitet dobar, nego još i kako "paše" sa ostalim entitetama u kontekstu. Onda sam napravio samo kako ce se ti ValidatorResult-i prikazivati u Asp.Net aplikaciji, Forms aplikaciji ili WPF aplikaciji i nisam ogranicen time kako je MS predvideo da se validiraju entiteti.

Možda postoji neki bolji, ugađeni način ali ga ja nisam našao tada kada sam pravio svoje osnovne frameworke i meni ovo radi odlično.
if it walks like a duck and quacks like a duck, it could be a dragon doing a duck
impersonation.
 
Odgovor na temu

Mikelly

Član broj: 16730
Poruke: 389
77.222.26.*



Profil

icon Re: Entity Framework, Combobox DataBinding po kompozitnom kljucu...07.03.2011. u 06:52 - pre 159 meseci
U, jako zanimljivo. Lici na IDataErrorInfo pomalo.

Par pitanja, ako te ne mucim.

DataError enumeracije i to si ti napravio?

Moras li eksplicitno da pozoves metod Validate ili se poziva implicitno. Pretpostavljam da moras, cim mu prosledjujes context. Cudna stvar, u EF-u ne se ne moze na osnovu entiteta dobiti context...

I na kraju, kako prikazujes greske? Ustvari, kako uopste poslije nadjes tu gresku? Preko Entity promjenljive u ValidatorResult klasi?

Super nema sta.
 
Odgovor na temu

Boris B.
Ljubljana

Član broj: 213615
Poruke: 286
*.evj-kabel.net.



+14 Profil

icon Re: Entity Framework, Combobox DataBinding po kompozitnom kljucu...07.03.2011. u 18:45 - pre 159 meseci
Citat:
Mikelly
DataError enumeracije i to si ti napravio?

DataError je prosta enumeracija da bi greške bile strongly-typed, onda možeš da pravis i lepe rečnike sa detaljnim opisima, da specijalno reaguješ u UI-u na određenu grešku i sl.

Citat:
Mikelly
Moras li eksplicitno da pozoves metod Validate ili se poziva implicitno. Pretpostavljam da moras, cim mu prosledjujes context.

Poziva ga neki moj DataManager (koji enkapsulira context) pre nego što radi Context.SaveChanges, tako što za svaki Added i Changed objekat u ObjectStateManageru zove Validate. Implicitna validacija možda ne bi bila dobra, jer ćeš u praksi više puta namerno imati entitet u nekom prelaznom stanju koje nije validno, mislim da je bolje samo se osigurati da se invalid entitet ne zapiše u bazu.

Citat:
Mikelly
Cudna stvar, u EF-u ne se ne moze na osnovu entiteta dobiti context...


Može, samo treba malo posla. ObjectContext ima event ObjectMaterialized koji se desi svaki put kada se neki EntityObject kreira
Code (csharp):

public interface IContextProvider
{
    ObjectContext Context { get; set; }
}

...

partial class Osoba : IContextProvider
{
    ObjectContext Context { get; set; }
}

...

Context.ObjectMaterialized += (sender, args) => { if (args.Entity is IContextProvider) (args.Entity as IContextProvider).Context = sender as ObjectContext; };
 


Citat:
Mikelly
I na kraju, kako prikazujes greske? Ustvari, kako uopste poslije nadjes tu gresku? Preko Entity promjenljive u ValidatorResult klasi?

Greške prikazuješ kako hoćeš. ValidatorResult.Entity ti kaže koji entitet (mada je to najčešće upravo objekat koji je otvoren u editoru kad klikneš OK pa ne uspe), ValidatorResult.FieldName ti kaže koji property tako da možeš preko databindinga da nađeš editor, ValidatorResult.Error ti kaže kod greške da možeš u klient-rečniku da nađeš lepu, user-friendly poruku.

I pazi kad radiš sa kontekstima da ih što pre uništavaš i praviš druge, najbolje je da svaki UI kontejner (Prozor, ASP.Net stranica, štagod) ima svoj kontekst, a podatke između njih prosleđuješ tako što prosleđuješ EntityKey entiteta. Ima mnogo da se kaže na sve ove teme oko EF, na toliko stvari mora da se pazi da se stvarno pitam da li se isplati...


if it walks like a duck and quacks like a duck, it could be a dragon doing a duck
impersonation.
 
Odgovor na temu

Mikelly

Član broj: 16730
Poruke: 389
*.crnagora.net.



Profil

icon Re: Entity Framework, Combobox DataBinding po kompozitnom kljucu...08.03.2011. u 06:55 - pre 159 meseci
Fala Borise, uvijek mi prija da vidim kako drugi rjesavaju konkretne probleme.

Jos mi reci samo ovo, necu te vise mucit :)

Kako rjesavas probleme filtriranja i sortiranja entiteta? Ako CollectionViewSource ima za Source svojstvo samo recimo context.EntitySet filtiranje ne radi po defaultu. Ako uopste koristis CollectionViewSource. Mada cvs ima super stvari, kao grupisanje npr. Ja konvertujem (rucno) EntitySet u neku listu pa onda predikatom definisem filter. Ne znam da li je to dobro rjesenje.

Pozdrav.
 
Odgovor na temu

Boris B.
Ljubljana

Član broj: 213615
Poruke: 286
*.zaslon-telecom.si.



+14 Profil

icon Re: Entity Framework, Combobox DataBinding po kompozitnom kljucu...08.03.2011. u 09:01 - pre 159 meseci
Ne koristim CollectionViewSource iz prostog razloga što nisam naleteo na njega onda kada sam počinjao, tako da pravo da ti kažem ni ne znam čemu služi, pogledaću svakako.

Koristim prosti BindingSource i shapujem rezultate onako kako mi treba za dati prikaz, nešto kao:

Code (csharp):

public class OsobaViewItem
{
    public OsobaViewItem(Model.Osoba o)
    {
        ImeIPrezime = string.Format("{0} {1}", o.Ime, o.Prezime).Trim();
    }
    public string ImeIPrezime { get; private set; }  
}

...

BindingSource.DataSource = Manager.Osoba.Query.Where(o => o.Aktivna).OrderBy(o => o.RedniBroj).ThenBy(o => o.Prezime).Select(o => new OsobaViewItem(o)).ToList();
 


Lepota je što se sve proverava prilikom kompajliranja, nemaš nigde polje/tabelu/uslov kao string, tako da ako se kompajlira su velike šanse da će i da radi

Možeš celu stvar sa filtriranjem da odvedeš i korak dalje u statičko proveravanje koristeći Linq Expressions i expression rewriting, ako te bude zanimalo viči, mada ima dosta koda
if it walks like a duck and quacks like a duck, it could be a dragon doing a duck
impersonation.
 
Odgovor na temu

[es] :: .NET :: Entity Framework, Combobox DataBinding po kompozitnom kljucu...

[ Pregleda: 1878 | Odgovora: 9 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.