Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11
  1. #1
    Utente di HTML.it L'avatar di cassano
    Registrato dal
    Aug 2004
    Messaggi
    3,002

    Entityframework 5 controllo oggetti in memoria

    Ciao a tutti vi spiego il mio problema.

    Faccio un ciclo su un file di testo e mano a mano aggiungo dei record nel database.

    Può succedere che in questo file di testo ci siano dei duplicati, che quindi non devono essere importati.

    Come faccio a controllare se in memoria c'è già quel record prima di salvare i dati nel database ?

  2. #2
    Utente di HTML.it L'avatar di U235
    Registrato dal
    Mar 2006
    Messaggi
    1,539
    Ciao!
    Mi sembra un pò troppo banale la risposta, quindi presumo che le tue difficoltà non siano molto comprensibili...
    a primo impatto comunque ti risponderei di controllare la lista Local della proprietà del context che stai utilizzando prima di aggiungerli in memoria ma come già detto sarebbe troppo banale e la risposta sarebbe intrinseca nella domanda...

    diciamo che dovresti esporre meglio il tuo problema, magari specificando se usi code first o database first, potresti specificare dove istanzi il contesto e dove lo chiudi e dove fai il controllo per capire se sono doppioni, magari postando anche un pò di codice...

  3. #3
    Utente di HTML.it L'avatar di cassano
    Registrato dal
    Aug 2004
    Messaggi
    3,002
    Allora queste sono le operazioni effettuate :

    1)Apro un file di testo , leggo riga per riga e lo splitto
    2)Prendo il primo valore che è un codice univoco ,vedo se è già presente nel database.
    3)Se non è presente nel database lo aggiungo al contesto altrimenti vado avanti.

    Ora può succedere che durante il ciclo sul file di testo, ci siano record duplicati che ovviamente non avendo salvato nulla ancora sul database, risulta inesistente sul db, e quindi aggiungerei un duplicato sul database.

    C'è un modo per controllare il contesto di EF e vedere se un record aggiunto in memoria già esista ?

  4. #4
    Utente di HTML.it L'avatar di U235
    Registrato dal
    Mar 2006
    Messaggi
    1,539
    Ciao!
    Io ho sempre usato code first, quindi il mio contesto è sempre stato un derivato di DbContext, ma credo sia uguale anche con le classi scritte da vs, visto che se non sbaglio da ef 5 con vs 2012 dovrebbe essere stato introdotto il DbContext come tipo di base di ef (ma non ne sono certo visto che non uso l'approccio creato da vs, mi scrivo direttamente le classi e le mappo). In ogni caso credo sia simile...
    In sostanza il tuo contesto, prima di memorizzare i dati, li tiene nella lista local di ogni proprietà (di tipo DbSet<T>), queste proprietà contengono un lista "Local" (di tipo ObservableCollection<T>) dove vanno a finire tutte le entita (di tipo T) che hai aggiunto alle proprietà (DbSet<T>), ovviamente queste entità che hai aggiunto ma che ancora non hai salvato nel db avranno un ID inferiore a 1 (se hai utilizzato un int come primary key), quindi in ogni caso sarebbe facile controllare se tra di loro esiste un doppione.

    se poi vuoi un consiglio ti direi di far derivare le tue classi "entità" (nella quale vuoi fare un controllo degli errori) dalla IValidatableObject implementando il metodo Validate, in questo modo se esegui l'override del ValidateEntity nella classe derivata dal tuo DbContext (quella che contiene le liste DbSet<T>), puoi ottenere il controllo degli errori chiamando il metodo DbContext.GetValidationErrors() in qualsiasi momento e ovunque usi il modello, inoltre volendo puoi agire direttamente nel Validate in modo che non venga neanche aggiunta una ipotetica entità errata.

    Spero di aver capito bene ciò che vuoi ottenere...

  5. #5
    Utente di HTML.it L'avatar di cassano
    Registrato dal
    Aug 2004
    Messaggi
    3,002
    Ma chiedo non esiste la possibilità di fare delle query sulle entity che ancora non sono state salvate sul DB ?

    Per esempio coi dataset , una volta aggiunto un record e prima di salvarlo sul db, potevi fare un ciclo al suo interno per vedere se alcuni record erano già presenti.
    Insomma era come avere un db ma in memoria.

  6. #6
    Utente di HTML.it L'avatar di U235
    Registrato dal
    Mar 2006
    Messaggi
    1,539
    Originariamente inviato da cassano
    Ma chiedo non esiste la possibilità di fare delle query sulle entity che ancora non sono state salvate sul DB ?

    Per esempio coi dataset , una volta aggiunto un record e prima di salvarlo sul db, potevi fare un ciclo al suo interno per vedere se alcuni record erano già presenti.
    Insomma era come avere un db ma in memoria.
    Ma certo che si! esattamente come ti ho scritto nel mio post precedente...

    diciamo che l'esempio l'avresti dovuto fare tu con il tuo codice, anche per capire le cose importanti che ti ho chiesto prima e alle quali non hai risposto... in ogni caso ti posto un esempio banale :

    Model.cs
    codice:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Data.Entity;
    
    namespace ConsoleApplication1
    {
        public class DB : DbContext
        {
            public DB()
                : base("name=DBModel")
            { }
    
            public DbSet<FileTXT> Files { get; set; }
        }
    
        public class FileTXT
        {
            public int ID { get; set; }
            public string Text { get; set; }
        }
    }
    Program.cs
    codice:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Data.Entity; 
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                FileTXT[] Files = new FileTXT[]
                {
                    new FileTXT() { Text = "AAAjjansndfn" },
                    new FileTXT() { Text = "AAAjjansndfn12" },
                    new FileTXT() { Text = "AAAjjansndfn" },
                    new FileTXT() { Text = "AAAjjansndfn23" },
                    new FileTXT() { Text = "AAAjjansndfn" },
                    new FileTXT() { Text = "AAAjjansndfn12" }
                };
    
                using (DB db = new DB())
                {
                    //con questo carico le entità nella lista Local (se le voglio...)
                    db.Files.Load();
    
                    //diversamente, se voglio controllare eventuali doppioni SOLO tra 
                    //quelle non ancora salvate, posso non far caricare le entità
                    //(tolgo db.Files.Load())
                    //MA ATTENZIONE : in questo caso una volta che chiamo la lista (non Local, quindi db.Files.Any ad esempio)
                    //automaticamente verranno caricate tutte le entità nella Local (già salvate e non)
                    //quindi se sei interessato al controllo delle sole entità non salvate conviene 
                    //distinguerle dall'ID (salvate >0, non salvate<1)
                    
                    Files.ToList().ForEach(file=>//controllo eventuali doppioni tra tutte
                    {
                        if (!db.Files.Local.Any(a => a.Text == file.Text)) db.Files.Add(file);
                    });
    //EDIT ERRORE  :fagiano: 
                    db.SaveChanges();
                }
            }
        }
    }
    in questo caso, come prova di concetto, prima di aggiungere un entità controllo che questa non abbia la proprietà Text uguale a qualche altra già in memoria, se non c'è l'aggiungo, ma il controllo lo avrei potuto fare anche alla fine con tutte le entità aggiunte, quelle doppie le elimino. Solo alla fine salvo nel DB (.SaveChanges(); ).

  7. #7
    Utente di HTML.it L'avatar di cassano
    Registrato dal
    Aug 2004
    Messaggi
    3,002
    codice:
       Using db As New aaaaaEntities
    
          for each riga in l.readlines
                 db.nometabella.add(riga)
           next
    
           db.save
    
    end using
    Adesso prima di db.nometabella.add(riga) dovrei fare un controllo se quel record esiste

    tipo if db.nometabella.recordesisate(riga.campo) = false.....

  8. #8
    Utente di HTML.it L'avatar di U235
    Registrato dal
    Mar 2006
    Messaggi
    1,539
    Originariamente inviato da cassano
    codice:
       Using db As New aaaaaEntities
    
          for each riga in l.readlines
                 db.nometabella.add(riga)
           next
    
           db.save
    
    end using
    Adesso prima di db.nometabella.add(riga) dovrei fare un controllo se quel record esiste

    tipo if db.nometabella.recordesisate(riga.campo) = false.....
    quel "save" spero sia un SaveChanges, diversamente mi sorgerebbe il dubbio che tu stia utilizzando effettivamente Entity Framework 5... magari se avessi specificato anche i tipi sarebbe stato meglio. In ogni caso, ammettendo che sia solo un errore di battitura, mi sembra abbastanza semplice quello che dovresti fare, l'ho gia scritto in 2 post, questo sarebbe il terzo...

    se aaaaaEntities è di tipo derivato da DbContext, allora significa che db.nometabella è di tipo DbSet<T>, quindi "riga" e una nuova istanza di tipo T, a questo punto, prima di aggiungere l'oggetto "riga" fai un controllo su db.nometabella.Any (linq) per vedere se la proprietà del tipo "riga" che determina l'uguaglianza tra un oggetto e l'altro non esista già tra quelli già presenti.

    se poi c'è qualcosa che non ti quadra, specifica meglio la tua situazione

    EDIT :
    la proprietà che determina l'uguaglianza dell'oggetto sarebbe quello che tu chiami campo, che altro non è che una proprietà del tipo mappatto con la tabella del db.
    In EF le tabelle sono di tipo DbSet<T> (e sono proprietà del contesto) mentre le righe sono istanze di tipo T, e i campi sono proprietà del tipo T.

  9. #9
    Utente di HTML.it L'avatar di cassano
    Registrato dal
    Aug 2004
    Messaggi
    3,002
    Grazie per la risposta.
    Si era SaveChanges, stavo col cellulare e non me ne sono accorto scusa.

    Tu dici di usare db.nometabella.Any, ma quando lo faccio lui ovviamente fa la query verso il database fisico e non verso il "database" in memoria.

    Ovviamente non avendo fatto ancora il salvataggio dei record, lui non lo troverà.

    Forse non ci sto capendo nulla ?

  10. #10
    Utente di HTML.it L'avatar di U235
    Registrato dal
    Mar 2006
    Messaggi
    1,539
    Ciao!
    Hai provato? immagino di no... Le entità aggiunte ma non ancora salvate vengono inserite con un id inferiore ad uno (solitamente tutte a 0), dopo il savechanges vengo assegnati gli id corretti (perché in quel momento le salvi nel db) ma nella lista sono presenti nel momento che li aggiungi... É semplicemente una lista, se aggiungi qualcosa ad una lista questa ci sarà per forza

    Ovviamente tutto questo deve avvenire nello stesso contesto, ovvero devi aggiungere ed interrogare l'oggetto nella quale le hai aggiunte, se lo chiudi (ad esempio provi dopo la direttiva using) tutte le modifiche non salvate saranno perse, di conseguenza troverai solo i dati del db.

    Non é che per caso il tuo scenario é questo? Se é così non chiudere l'oggetto con using, ma fallo a mano quando hai terminato. in ogni caso ti basta fare in modo che aggiungi tutte le entità dallo stesso contesto (lo stesso oggetto) per poter tranquillamente fare i controlli sia su quelle già salvate che su quelle aggiunte.


Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.