Login Login
MORE

WIDGETS

Widgets

Wanted articles
Who is online?
Article tools

CSharp:Esempi LinQ fusione datatable

From Aino Wiki

Jump to: navigation, search

Esempio completo funzionante:

        public static DataTable Step5_MergeDataTable(string fileNameValue, Dictionary<string, InfoMappingAndRules> dictInfoMapping4File,
                                                    DataSet dsSourceFiles, List<SynchronizationsDownloads> lsd,
                                                    ref List<SynchronizationsMapping> lsm, ref string strMsgError)
        {
            DataTable dtFull = new DataTable();
            strMsgError = string.Empty;
            string[] arrFileToImport = fileNameValue.Split(',');
            string strCSVAllPositionToRemove = string.Empty;
            int nrFieldsOk = 0;
            int positionToRemove = -1;
            int i = 0;
            string synchronizationID = lsd.Count > 0 ? lsd[0].SynchronizationID : string.Empty;
 
            #region CREAZIONE elenco di tutti i mapping per TUTTI Files\DataTable --> tabella finale
            //Si crea un lsm con tutti i mapping per la Synchro quindi adatti ad un unico DataTable complessivo
            //ciò escludendo i campi di mapping DOPPIONI
            foreach (SynchronizationsDownloads sd in lsd)
            {
                List<SynchronizationsMapping> lsmX = new List<SynchronizationsMapping>();
                if (dictInfoMapping4File.ContainsKey(sd.DestinationFileName))
                {
                    lsmX = dictInfoMapping4File[sd.DestinationFileName].LstSyncMappings;
                    foreach (SynchronizationsMapping sm in lsmX)
                    {
                        if (!SynchronizationsMapping.SourceColumnAlreadyAdded(lsm, sm)
                            && !sm.DestinationColumnName.Contains(SynchronizationsMapping.RootNameDestField4FilterRules)) 
                        {
                            lsm.Add(sm);
                        } 
                        //else 
                        //{ i++; //PER DEBUG !!!! conta gli scartati
                        //}
                    }
                }
            }
            #endregion
 
            #region Costruzione Info x trasformazione in funzine del Tipo colonna tabella Import
            //Dictionary<string, string> dictColDestType = new Dictionary<string, string>();              //Contiene i tipi dei campi della Tabella IMPORT 
            //string secondKeyFieldName = string.Empty;
            //Dictionary<string, string> dictColMapping = BuildDictColMapping(lsm, ref secondKeyFieldName, ref dictColDestType);
            #endregion
 
            if (arrFileToImport.Length > 1)
            {
                #region CASO PIU' DI un File\DataTable
                dtFull = dsSourceFiles.Tables[arrFileToImport[0]].Clone(); //<-- Di Default E PER IPOTESI, il primo file è quello più importante con info pilota
                nrFieldsOk = dsSourceFiles.Tables[arrFileToImport[0]].Columns.Count;
 
                //Nome campo corrispondente al ProductCode della tabella di Import
                string sourceKeyFieldName0 = string.Empty;
                string sourceKeyFieldName1 = string.Empty;
                sourceKeyFieldName0 = SynchronizationsMapping.GetSourceColumnIndexKeyByDestinationFileName(lsd, dictInfoMapping4File[arrFileToImport[0]].LstSyncMappings, arrFileToImport[0]);
                sourceKeyFieldName1 = SynchronizationsMapping.GetSourceColumnIndexKeyByDestinationFileName(lsd, dictInfoMapping4File[arrFileToImport[1]].LstSyncMappings, arrFileToImport[1]);
                string destinationKeyFieldName = SynchronizationsMapping.GetKeyFieldNames(lsm); //E' unico ed è: ProductCode
 
                #region CREAZIONE MATRICE dei valori da riporre nel nuovo DT omnicomprensivo
                object[] emptyObj = new object[dsSourceFiles.Tables[arrFileToImport[1]].Columns.Count];
                //if (synchronizationID == "ESPSYN")
                //{
                //    emptyObj = new string[] { "xxx", "0", "0" }; //emptyObj = new string[] { "xxx", "-9999", "-9999" };
                //}
 
                //Prima MATRICE DI VALORI per la prima COPPIA di Files\Datatable da integrare per ogni file successivo al SECONDO
                var rowData = from
                                    row1 in dsSourceFiles.Tables[arrFileToImport[0]].AsEnumerable()
                                join
                                    row2 in dsSourceFiles.Tables[arrFileToImport[1]].AsEnumerable()
                                on
                                    row1.Field<string>(sourceKeyFieldName0).Trim() equals row2.Field<string>(sourceKeyFieldName1).Trim() into row1X
                                from rowY in row1X.DefaultIfEmpty()
                                select
                                    row1.ItemArray.Concat(rowY == null ? emptyObj : rowY.ItemArray).ToArray(); //row1.ItemArray.Concat(rowY == null ? new object[0] : rowY.ItemArray).ToArray();
 
                //CICLO x ogni altro file se c'è, successivo al primo
                //per eliminare i valori di informazioni RIPETUTE una su tutte è il campo chiave che deve essere in ciascun file/DataTable!!!
                //Preliminare, segno tutti i campi del primo file
                foreach (DataColumn dc in dtFull.Columns)
                {
                    SynchronizationsMapping.GetDestinationColumNameAndMark(lsm, dc.ColumnName);
                }
 
                string destinationColumName = string.Empty;
                //dal secondo file e relativo gruppo di colonne
                for (int f = 1; f < arrFileToImport.Length; f++)
                {
                    string sourceKeyFieldNameF = string.Empty;
                    i = 0; positionToRemove = -1;
                    //Costruisce l'insieme delle colonne di 2 File ovvero DataTable
                    var dt2Columns = dsSourceFiles.Tables[arrFileToImport[f]].Columns.OfType<DataColumn>()
                                                                                        .Select(dc => new DataColumn(dc.ColumnName, dc.DataType, dc.Expression, dc.ColumnMapping));
                    //Aggiunge al DataTable PRINCIPALE 'dtFull'  le colonne degli altri files
                    foreach (DataColumn dc in dt2Columns)
                    {
                        if (!dtFull.Columns.Contains(dc.ColumnName))
                        {
                            destinationColumName = SynchronizationsMapping.GetDestinationColumNameAndMark(lsm, dc.ColumnName);
                            if (destinationColumName == destinationKeyFieldName) //non si aggiunge la colonna se il Destination Field è Chiave
                            {
                                positionToRemove = i;
                            }
                            else
                            {
                                dtFull.Columns.Add(dc);
                            }
                        }
                        else
                        {
                            destinationColumName = SynchronizationsMapping.GetDestinationColumNameAndMark(lsm, dc.ColumnName);
                            if (destinationColumName == destinationKeyFieldName)
                                positionToRemove = i; // è UNO solo, per ipotesi !!!            ed è relativo al file\DataTable corrente
                            else
                            {
                                string newSourceColumnIndex = dc.ColumnName + "#" + destinationColumName;
                                //ridenominare anche il source del mapping
                                dc.ColumnName = SynchronizationsMapping.RenameSourceColumnIndex(lsm, dc.ColumnName, destinationColumName, newSourceColumnIndex);
                                dtFull.Columns.Add(dc);
                            }
                        }
                        i++;
                    }
                    //Aggiustamento posizione
                    if (positionToRemove > -1)
                    {
                        positionToRemove += nrFieldsOk + positionToRemove;
                        nrFieldsOk += i;
                        strCSVAllPositionToRemove += (string.IsNullOrEmpty(strCSVAllPositionToRemove) ? "," : string.Empty) +
                                                    positionToRemove + ",";
                    }
                    //Integrazione della MATRICE DI VALORI, per le coppie di DataTable successive alla prima quindi dalla coppia 3-4 DataTable
                    if (f > 1)
                    {
                        int nrColSecondFile = dsSourceFiles.Tables[arrFileToImport[f]].Columns.Count; //ATTENZIONE NON CANCELLARE O SPOSTARE => Baco di Linq, non calcolerebbe correttamente il nr di colonne
                        sourceKeyFieldNameF = SynchronizationsMapping.GetSourceColumnIndexKeyByDestinationFileName(lsd,
                                                dictInfoMapping4File[arrFileToImport[f]].LstSyncMappings, arrFileToImport[f]);
                        rowData = from
                                        row1 in rowData
                                    join
                                        row2 in dsSourceFiles.Tables[arrFileToImport[f]].AsEnumerable()
                                    on
                                        row1[0] equals row2.Field<string>(sourceKeyFieldNameF).Trim() into row1X
                                    from rowY in row1X.DefaultIfEmpty()
                                    select
                                            row1.Concat(rowY == null ? new object[nrColSecondFile] : rowY.ItemArray).ToArray();
                    }
                } //Fine file\DataTable corrente
                #endregion
 
                //Riempimento DataTable con i Valori dai 2\n DataTable.       rowData    ha TUTTI i valori !!!
                int rowInserted = 0;
                int j = 0;
                try
                {
                    if (!string.IsNullOrEmpty(strCSVAllPositionToRemove))
                    {
                        foreach (object[] values in rowData) //Riga definitiva con TUTTI i valori da porre nel DataTable DESTINAZIONE
                        {
                            j = 0;
                            DataRow dr = dtFull.NewRow();
                            for (int c = 0; c < values.Length; c++)
                            {
                                if (strCSVAllPositionToRemove.IndexOf("," + c + ",") < 0)
                                {
                                    //string destinationColumnName = dictColMapping[ dr.Table.Columns[j].ColumnName];
                                    //dr[j] = TransformFieldValueByDestType(singleValue, destinationColumnName, dictColDestType, true);
                                    //string singleValue = values[c].ToString();
                                    dr[j] = values[c];
                                    j++;
                                }
                            }
                            dtFull.Rows.Add(dr);
                            rowInserted++;
                        }
                    }
                    else
                    {
                        #region Caso IMPROBABILE, nessun campo chiave di collegamento
                        foreach (object[] values in rowData)
                        {
                            DataRow dr = dtFull.NewRow();
                            for (int c = 0; c <= dtFull.Columns.Count; c++)
                            {
                                dr[c] = values[c];
                            }
                            dtFull.Rows.Add(dr);
                        }
                        #endregion
                    }
                }
                catch (Exception ex)
                {
                    string lastProdCode = string.Empty;
                    strMsgError = string.Format("Errore: {0}.\r\nRighi inseriti: '{1}', j='{2}'", ex.Message, rowInserted, j);
                    try 
                    {
                        lastProdCode = dtFull.Rows[rowInserted-1][sourceKeyFieldName0].ToString();
                    } catch {}
                    strMsgError = string.Format("{0}, ultimo productCode '{1}'", strMsgError, lastProdCode); //Serve a poco perchè l'ordinamento di inserimento è diverso......
                }
                #endregion
            }
            else //Caso un solo file da porre in DataTable:
            {
                dtFull = dsSourceFiles.Tables[arrFileToImport[0]];
            }
            //Verifica finale
            if (dtFull.Rows.Count == 0)
            {
                strMsgError = "Nessuna informazione nel DataTable completo da importare sl DB.";
            }
            return dtFull;
        }



C# | LinQ | Esempi LinQ

Author Giuseppe AINO