none
EF 4.1 Delete senza Caricare Entity

    Domanda

  • 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

     

    sabato 7 gennaio 2012 15:21

Tutte le risposte


  • 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
    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


    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

    martedì 17 gennaio 2012 21:49
  • 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
    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


    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 10:47
  • 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 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


    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

    domenica 22 gennaio 2012 18:45