EF 4.1 Delete senza Caricare Entity
-
sabato 7 gennaio 2012 15:21
salve a tutti,
sto cercando di eliminare una enity senza prima caricarla.
ho le seguenti classi :public class Contact { public Guid ID { get; set; } public string Surname { get; set; } public string Name { get; set; } public virtual City BirthCity { get; set; } } public class City { public Guid ID { get; set; } public string Name { get; set; } }questa la configurazione della relazione
modelBuilder.Entity<DomainModel.Contact>().HasRequired(c => c.BirthCity).WithMany().Map(map => map.MapKey("BirthCityID")).WillCascadeOnDelete(false);
per cancellare faccio in questo modo :
C = new Contact() ; C.ID = new Guid("abd6b974-575e-492e-976d-a8bd4f4a24d2"); DB.Contacts.Attach(C); DB.Entry(C).State=System.Data.EntityState.Deleted; DB.SaveChanges();
Al saveChanges, ottengo l'errore
Le entità in 'Contacts' fanno parte della relazione 'Contact_BirthCity'. Trovati 'Contact_BirthCity_Target' correlati a 0. Previsto 1 'Contact_BirthCity_Target'.In pratica vuole che imposto anche la birth city?
Se però cambio la relazione in
modelBuilder.Entity<DomainModel.Contact>().<strong>HasOptional</strong>(c => c.BirthCity).WithMany().Map(map => map.MapKey("BirthCityID")).WillCascadeOnDelete(false);
La cancellazione avviene senza problemi, però la relazione sul DB è not null quindi cosi il modello non mi corrisponde più al DB.Ho provato a cercare, ma in tutti gli esempi che ho trovato, il metodo funziona e non si fa cenno alla situazione con HasRequired.
Sapreste indicarmi come poter risolvere senza alterare il modello?
ciao e grazie.P.S.
Vi prego di non consideare un cross post questo con quello su Data Services, se trovo la soluzione du EF, poi cerco di riportarla ai DS
Tutte le risposte
-
venerdì 13 gennaio 2012 13:53
scusa la mia ingnoranza, ma non ho capito perché vuoi fare questa operazione.....comunque, se la relazione è obbligatoria, hai provato a metterla prima di cancellare?
C = new Contact() ; C.ID = new Guid("abd6b974-575e-492e-976d-a8bd4f4a24d2"); C.City = new BirthCity(new Guid("xxxx")); //o qulacosa già caricato DB.Contacts.Attach(C); DB.Entry(C).State=System.Data.EntityState.Deleted; DB.SaveChanges();
Programamtore ASP.NET
http://glucolo.wordpress.com -
martedì 17 gennaio 2012 21:49
scusa la mia ingnoranza, ma non ho capito perché vuoi fare questa operazione.....comunque, se la relazione è obbligatoria, hai provato a metterla prima di cancellare?
C = new Contact() ; C.ID = new Guid("abd6b974-575e-492e-976d-a8bd4f4a24d2"); C.City = new BirthCity(new Guid("xxxx")); //o qulacosa già caricato DB.Contacts.Attach(C); DB.Entry(C).State=System.Data.EntityState.Deleted; DB.SaveChanges();
Programamtore ASP.NET
http://glucolo.wordpress.com
Ciao,Metti caso di avere una entity mediamente complessa ma in una form hai una lista con codice e descrizione(quindi faccio una proiezione e non tiro su tutte le Entity). Sulla lista posso selezionare una riga e premere il pulsante cancella. In questa situazione, posso evitare di caricare l'intera entity, solo per cancellarla.
Il fatto è che se carico l'entity senza caricare la relazione, posso cancellarla senza problemi quindi vorreiriuscire a cancellarla in questo altro modo senza dovergli specificare la relazione
Ciao
-
mercoledì 18 gennaio 2012 14:05
ok, ho capito perché voi farlo, gistamente è inutile ricaricare tutta la path solo per cancellare l'elemento.
Be, come ti ho detto prima, se l'elemento che vuoi cancellare è completo di relazione, EF te lo lascia cancellare (in teoria).
conosci la chiave con la BirthCity quando vai a cancellare l'elemento?C = new Contact() ; C.ID = new Guid("abd6b974-575e-492e-976d-a8bd4f4a24d2"); //non mi ricordo bene, ti scrivo entrambe le ipotesi //1 C.City = new BirthCity(new Guid("xxxx")); //2 C.BirthCitysReference.EntityKey = new EntityKey("BirthCitys", "CityId", xxxx); DB.Contacts.Attach(C); //1 DB.Entry(C).State=System.Data.EntityState.Deleted; //2 DB.DeleteObject(post); DB.SaveChanges();
Un'altra soluzione sarebbe quella di avere una SP sul DB che cancella un contatto passando l'ID.
Porti su EF la SP come funzione, e usi quella.ciao
Programamtore ASP.NET
http://glucolo.wordpress.com- Modificato Glauco Cucchiar mercoledì 18 gennaio 2012 14:07
-
domenica 22 gennaio 2012 10:47
ok, ho capito perché voi farlo, gistamente è inutile ricaricare tutta la path solo per cancellare l'elemento.
Be, come ti ho detto prima, se l'elemento che vuoi cancellare è completo di relazione, EF te lo lascia cancellare (in teoria).
conosci la chiave con la BirthCity quando vai a cancellare l'elemento?C = new Contact() ; C.ID = new Guid("abd6b974-575e-492e-976d-a8bd4f4a24d2"); //non mi ricordo bene, ti scrivo entrambe le ipotesi //1 C.City = new BirthCity(new Guid("xxxx")); //2 C.BirthCitysReference.EntityKey = new EntityKey("BirthCitys", "CityId", xxxx); DB.Contacts.Attach(C); //1 DB.Entry(C).State=System.Data.EntityState.Deleted; //2 DB.DeleteObject(post); DB.SaveChanges();
Un'altra soluzione sarebbe quella di avere una SP sul DB che cancella un contatto passando l'ID.
Porti su EF la SP come funzione, e usi quella.ciao
Programamtore ASP.NET
http://glucolo.wordpress.com
Ciao,Ho finalmente trovato un po di tempo per fare qualche prova.
quando scrivi
C.BirthCitysReference.EntityKey = new EntityKey("BirthCitys", "CityId", xxxx);
Sto usando l'approccio codefirst, quindi BirthCitysReference non è presente nelle mie entity.
Ho anche provato a fare il detach da una entity precaricata
Contact C = null; using (MioDocContext DB = new MioDocContext()) { Guid G = new Guid("eb743f79-8494-46d4-9417-013c3c49ad6f"); C = DB.Contacts.Single(Co => Co.ID == G);; } using (MioDocContext DB = new MioDocContext()) { DB.Contacts.Attach(C); DB.Contacts.Remove(C); DB.SaveChanges(); }Ma al savechanges ottengo lo stesso errore.
Le entità in 'MioDocContext.Contacts' fanno parte della relazione 'Contact_BirthCity'. Trovati 'Contact_BirthCity_Target' correlati a 0. Previsto 1 'Contact_BirthCity_Target'
Che prova potrei fare per capire dove puo stare il problema?
ciao e grazie
-
domenica 22 gennaio 2012 14:16
ho trovato un post in un blog che parla dello stesso problema. Anche in questo articolo si cita le stesse prove e purtroppo c'è lo stesso errore.
Come soluzione anche questi nostri colleghi hanno implementato quello che ti ho suggerito prima:
una SP sul DB che cancella un contatto passando l'ID, portata su EF come funzione
Programamtore ASP.NET
http://glucolo.wordpress.com -
domenica 22 gennaio 2012 18:45
ho trovato un post in un blog che parla dello stesso problema. Anche in questo articolo si cita le stesse prove e purtroppo c'è lo stesso errore.
Come soluzione anche questi nostri colleghi hanno implementato quello che ti ho suggerito prima:
una SP sul DB che cancella un contatto passando l'ID, portata su EF come funzione
Programamtore ASP.NET
http://glucolo.wordpress.com
Ciao,il punto è che, cosi
Guid G = new Guid("eb743f79-8494-46d4-9417-013c3c49ad6f"); C = DB.Contacts.Single(Co => Co.ID == G);; DB.Contacts.Remove(C); DB.SaveChanges();ovviamente funziona, ma anche in questo caso, la relazione non è caricata(il Lazy è attivo) però c'è qualcosa di diverso nello stato della relazione, ma non riesco a trovarlo.
Con la store procedure mi lego al DB, sembra un controsenso volendo usare un ORM
Ciao

