10 messaggi dal 12 maggio 2012
Ciao a tutti ho un problemino e non riesco a risolverlo in maniera ottimale(evitandomi una marea di if)..vi spiego meglio:
devo fare delle INSERT DINAMICHE in un DB(sql Server 2012)tramite c# e interfacciandomi con linq o dataset non riesco a comporle.
Io ho una coppia <key,value> e in base alla key, che mi indica l'attributo gia presente nel db, inserire per esso il valore corrispondente.
Qualcuno puo darmi una mano..GRAZIE
11.886 messaggi dal 09 febbraio 2002
Contributi
ciao,

jiamy ha scritto:

interfacciandomi con linq o dataset non riesco a comporle.

sì, con DataSet (DataTable) dovresti riuscire. Prova così:

//Inizia definendo delle coppie chiave-valore fittizie.
//Io per questo esempio uso un dictionary.
var coppie = new Dictionary<string, string>();
coppie.Add("Nome", "Mario");
coppie.Add("Cognome", "Rossi");
coppie.Add("Eta", "32");

//Qui indica il nome della tabella su cui vuoi fare la Insert
const string NomeTuaTabella = "Anagrafica";
//Creo un SqlDataAdapter per recuperare lo schema della tabella dal db.
//Tranquillo, la query "SELECT * FROM ..." verrà eseguita
//con l'opzione FMTONLY ON, quindi non restituirà alcun record,
//ma serve solo a recupeare la struttura della tabella.
//Invece conn rappresenta il tuo oggetto SqlConnection
using (var adp = new SqlDataAdapter("SELECT * FROM " + NomeTuaTabella, conn))
{
    //mi creo una DataTable in cui metterò i valori della riga da aggiungere
    using (var dt = new DataTable())
    {
        //Lo schema della tabella viene copiato nel DataTable
        adp.FillSchema(dt, SchemaType.Source);
        //Ora creo la nuova riga da aggiungere
        var nuovaRiga = dt.NewRow();

        //effettuo un ciclo sul dizionario.
        foreach (string key in coppie.Keys)
        {
            //ogni valore viene copiato con la sua chiave
            //sulla nuova riga. Questa istruzione ti darà un
            //errore se la key non porta il nome di una colonna esistente.
            //Questo è positivo perché evita che eventuali manomissioni
            //all'input da parte dell'utente possano causare problemi
            nuovaRiga[key] = coppie[key];
        }

        //bene, ho copiato tutti i valori sulle rispettive colonne.
        //E' il momento di aggiungere la nuova riga al DataTable
        //Occhio: se non hai indicato i valori per tutte le colonne
        //obbligatorie (cioè quelle che non accettano null),
        //allora qui otterrai un errore.
        dt.Rows.Add(nuovaRiga);

        //Uso un SqlCommandBuilder che è in grado di crearmi
        //il comando INSERT osservando lo schema e i valori della nuova riga
        using (var builder = new SqlCommandBuilder(adp))
        {
            //Il SqlDataAdapter scoprirà che nel DataTable
            //è presente una riga con stato "Added"
            //e perciò effettuerà una INSERT nel DataBase.
            adp.Update(dt);
        }
    }
}



I tuoi campi sono tutti testuali oppure ne hai alcuni di tipo data o decimale? Attenzione che potresti incontrare delle ArgumentExceptions se i tuoi valori non riescono ad essere ricondotti al tipo di colonna presente nel database.

ciao
Modificato da BrightSoul il 31 maggio 2012 23.24 -

Enjoy learning and just keep making
10 messaggi dal 12 maggio 2012
grazie BrightSoul, io in realta avevo risolto in modo molto meno efficace del tuo cioe inserendo nel dataAdapter le varie insert e in base al valore della key del mio hashtable me la richiamo per poi fare un commit finale, ma cosi facendo non e' stata una costruzione dinamica ma a manina....pensa che ho piu di 1000 attributi ;)
Inoltre ho variato gli attributi del db tutti in stringa ma questo dovuto al fatto che uso XPathExpression per leggere determinati valori da piu file xml.
Ora provo la tua soluzione che gia' leggendo il codice sembra girare bene.
Ancora grazie
10 messaggi dal 12 maggio 2012
BrightSoul ha scritto:
ciao,

jiamy ha scritto:

interfacciandomi con linq o dataset non riesco a comporle.

sì, con DataSet (DataTable) dovresti riuscire. Prova così:

//Inizia definendo delle coppie chiave-valore fittizie.
//Io per questo esempio uso un dictionary.
var coppie = new Dictionary<string, string>();
coppie.Add("Nome", "Mario");
coppie.Add("Cognome", "Rossi");
coppie.Add("Eta", "32");

//Qui indica il nome della tabella su cui vuoi fare la Insert
const string NomeTuaTabella = "Anagrafica";
//Creo un SqlDataAdapter per recuperare lo schema della tabella dal db.
//Tranquillo, la query "SELECT * FROM ..." verrà eseguita
//con l'opzione FMTONLY ON, quindi non restituirà alcun record,
//ma serve solo a recupeare la struttura della tabella.
//Invece conn rappresenta il tuo oggetto SqlConnection
using (var adp = new SqlDataAdapter("SELECT * FROM " + NomeTuaTabella, conn))
{
    //mi creo una DataTable in cui metterò i valori della riga da aggiungere
    using (var dt = new DataTable())
    {
        //Lo schema della tabella viene copiato nel DataTable
        adp.FillSchema(dt, SchemaType.Source);
        //Ora creo la nuova riga da aggiungere
        var nuovaRiga = dt.NewRow();

        //effettuo un ciclo sul dizionario.
        foreach (string key in coppie.Keys)
        {
            //ogni valore viene copiato con la sua chiave
            //sulla nuova riga. Questa istruzione ti darà un
            //errore se la key non porta il nome di una colonna esistente.
            //Questo è positivo perché evita che eventuali manomissioni
            //all'input da parte dell'utente possano causare problemi
            nuovaRiga[key] = coppie[key];
        }

        //bene, ho copiato tutti i valori sulle rispettive colonne.
        //E' il momento di aggiungere la nuova riga al DataTable
        //Occhio: se non hai indicato i valori per tutte le colonne
        //obbligatorie (cioè quelle che non accettano null),
        //allora qui otterrai un errore.
        dt.Rows.Add(nuovaRiga);

        //Uso un SqlCommandBuilder che è in grado di crearmi
        //il comando INSERT osservando lo schema e i valori della nuova riga
        using (var builder = new SqlCommandBuilder(adp))
        {
            //Il SqlDataAdapter scoprirà che nel DataTable
            //è presente una riga con stato "Added"
            //e perciò effettuerà una INSERT nel DataBase.
            adp.Update(dt);
        }
    }
}



I tuoi campi sono tutti testuali oppure ne hai alcuni di tipo data o decimale? Attenzione che potresti incontrare delle ArgumentExceptions se i tuoi valori non riescono ad essere ricondotti al tipo di colonna presente nel database.

ciao
Modificato da BrightSoul il 31 maggio 2012 23.24 -


scusa il disturbo ma volevo, se puoi, delle delucidazioni sulle insert dinamiche.
Provo a spiegarmi meglio:
La mia funzione prende un arrayAssociativo(Dictionary) e un intero, tale intero mi indica la chiave secondaria della mia tabella e in funzione ad esso inserisco nel db i valori dell' arrayAssociativo.
Come faccio a inserire singolarmente l'intero in questione nel codice che mi hai mostrato?
Ti ringrazio in anticipo per la disponibilità.
11.886 messaggi dal 09 febbraio 2002
Contributi
ciao,
tu conosci il nome della colonna su cui si trova la chiave secondaria, giusto? Del resto conosci il nome della tabella, ti dovrebbe essere nota anche quella colonna.

In questo caso valorizza tale colonna subito prima di aggiungere la nuova riga al DataTable.
//qui valorizzo la colonna
nuovariga["ColonnaChiaveSecondaria"] = valoreChiaveSecondaria;

//e poi aggiungo la nuova riga, come nell'esempio precedente.
dt.Rows.Add(nuovaRiga);


Ho capito bene il problema?
Modificato da BrightSoul il 05 giugno 2012 23.40 -

Enjoy learning and just keep making
10 messaggi dal 12 maggio 2012
BrightSoul ha scritto:
ciao,
tu conosci il nome della colonna su cui si trova la chiave secondaria, giusto? Del resto conosci il nome della tabella, ti dovrebbe essere nota anche quella colonna.

In questo caso valorizza tale colonna subito prima di aggiungere la nuova riga al DataTable.
//qui valorizzo la colonna
nuovariga["ColonnaChiaveSecondaria"] = valoreChiaveSecondaria;

//e poi aggiungo la nuova riga, come nell'esempio precedente.
dt.Rows.Add(nuovaRiga);


Ho capito bene il problema?
Modificato da BrightSoul il 05 giugno 2012 23.40 -



Grazie per la dritta, posso chiederti un'ultima consulenza:
io sto creando la mia prima mvc 3 Application con c# e dai tutorial che ho visto devo obbligatoriamente crearmi il DbContext nel model, riscrivere le mie entita del db nelle varie classi per poi poter richiamare le funzioni nel controller e nella view(razor), oppure come sto facendo usare il tableAdapter anche se credo che vada fuori dalla politica mvc, almeno per come lo sto usando io cioe' creandomi le query nel db e richiamandole nelle funzioni del model grazie al tableAdapter.
Con Zend o altri framework usati io estendevo nella classe il db(class Myclass extend Zend_MyDB) e avevo gia tutti gli attributi del db, era il framework che lo mappava, poi facevo $this->nomeTabellaDelDB e avevo tutti gli elementi di quella tabella.
Come posso fare per avere una cosa del genere? Devo obbligatoriamente riscrivermi le entita nel Model e poi fare una classe DbContext per poter usare gli attributi o procedo con i tableAdapter inserendomi i valori come mi hai precedentemete mostrato?
Ti ringrazio ancora una volta per il supporto datomi, attendo tue notizie
11.886 messaggi dal 09 febbraio 2002
Contributi
ciao,
no, non sei obbligato a riscriverti le entità. Infatti, dato che tu hai già un database, puoi sfruttare l'approccio denominato appunto database first.
Visual Studio dispone di un designer che ti consente di autogenerare le classi del modello a partire dalla struttura del database.
Guarda questo video di Marco De Sanctis, ti spiega passo passo come procedere.
http://media.aspitalia.com/screencast/Entity-Framework-designer.media

Verso l'inzio del video, al minuto 1:20, lo vedrai aggiungere al progetto un "ADO.NET Entity Data Model". Questo genererà poi un contesto di tipo ObjectContext e delle classi di entità che ereditano da EntityObject.
Se vuoi fare in modo che le tue classi siano invece delle POCO (plain old CLR object), cioè delle semplici classi come le stai creando ora, che perciò non sono dipendenti da Entity Framework, allora puoi installare e aggiungere al progetto anche questo nuovo template:

EF 4.x DbContext Generator for C#
Le istruzioni su come installarlo si trovano nella descrizione ma se incontri difficoltà chiedi pure.

jiamy ha scritto:

dai tutorial che ho visto devo obbligatoriamente crearmi il DbContext nel model

Non è obbligatorio usarlo. Potresti anche utilizzare il TableAdapter ma scoprirai che con MVC e classi di entità è molto più semplice creare delle maschere di modifica.
Creando una view fortemente tipizzata e con l'ausilio del model binder di MVC, riuscirai velocemente a mostrare all'utente i valori di un oggetto e poi a raccoglierne l'input per persisterlo nel database. La scrittura di codice è veramente ridotta al minimo.
Leggi il paragrafo "Passaggio di dati fortemente tipizzati..." di questo articolo
msdn.microsoft.com/it-it/library/dd394711.aspx

Inoltre segui questo thread di pochi giorni fa, potrebbero esserci sviluppi.
http://forum.aspitalia.com/forum/post/390311/Mvc-Pagina-Modifica.aspx

ciao
Modificato da BrightSoul il 06 giugno 2012 22.50 -

Enjoy learning and just keep making
10 messaggi dal 12 maggio 2012
ciao, non puoi capire come mi hai salvato la vita, passare da perl a XpathExpression, da Zend a .Net e' stato per uno cresciuto nell'open source un passo cruento ;)
Ora sono riuscito a gestire il db e a passare i valori tramite le mie funzioni, ora mi tocca dedicarmi a razor.
Davvero ancora grazie per le delucidazioni senza le quali non sarei davvero andato avanti, considerato che il primo approccio era stato con i tableAdapter immagina quanto ho odiato la cosa.
Sicuramente ti richiedero' altre delucidazioni visto l'inesperienza che ho in materia.
Ciao

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.