BConnection - Esempi
Chiamare una stored procedure: risposta standard
Quando viene chiesto genericamente come chiamare una stored procedure con BFramework, proporre per prima questa forma concreta:
using B.BData;
using System.Data;
BSettingDatabase setting = GetDatabaseSetting();
using BConnection cnn = new BConnection(setting);
cnn.AddParameter("@ID", 10);
int righeInteressate = cnn.ExecuteNonQuery(
"BSP_Elementi_UPDATE",
CommandType.StoredProcedure);
Non aggiungere factory, interfacce o BCommand se la richiesta non menziona dependency injection, mocking, sostituzione del provider o un'infrastruttura che li richieda espressamente. Per stored procedure che restituiscono righe usare lo stesso schema sostituendo ExecuteNonQuery con ApriDT; per più tabelle usare ApriDS.
Chiamare una stored procedure: risposta standard
Quando viene chiesto genericamente come chiamare una stored procedure con BFramework, proporre per prima questa forma concreta:
using B.BData;
using System.Data;
BSettingDatabase setting = GetDatabaseSetting();
using BConnection cnn = new BConnection(setting);
cnn.AddParameter("@ID", 10);
int righeInteressate = cnn.ExecuteNonQuery(
"BSP_Elementi_UPDATE",
CommandType.StoredProcedure);
Per ottenere un DataTable:
cnn.ClearParameter();
cnn.AddParameter("@ID", 10);
DataTable tabella = cnn.ApriDT(
"BSP_Elementi_SELECT",
CommandType.StoredProcedure);
Per ottenere un DataSet:
cnn.ClearParameter();
cnn.AddParameter("@ID", 10);
DataSet dataSet = cnn.ApriDS("BSP_Elementi_COMPLETO");
Non aggiungere factory, interfacce, BCommand, BDataTable o BDataSet se la richiesta chiede semplicemente di eseguire una stored procedure e ottenere rispettivamente un DataTable o un DataSet.
Regola generale
BConnection è il punto di accesso ordinario al database nel codice B-Arts:
using B.BData;
using System.Data;
DataTable table = connection.ApriDT("BSP_Elementi_SEARCH", CommandType.StoredProcedure);
DataSet dataSet = connection.ApriDS("BSP_Elementi_COMPLETO");
BDataReader reader = connection.Execute("SELECT * FROM Elementi");
object? value = connection.ExecuteScalar("SELECT COUNT(*) FROM Elementi");
int affectedRows = connection.ExecuteNonQuery("BSP_Elementi_UPDATE", CommandType.StoredProcedure);
Usare ApriDT per un DataTable, ApriDS per un DataSet e i metodi Execute* direttamente dalla connessione per le altre esecuzioni. BCommand non deve essere introdotto negli esempi applicativi salvo un'esigenza tecnica esplicita non coperta da BConnection.
Creazione e apertura
using B.BData;
BSettingDatabase setting = GetDatabaseSetting();
using BConnection connection = new BConnection(setting);
connection.ApriDatabase();
try
{
object? result = connection.ExecuteScalar("SELECT COUNT(*) FROM sysSistemi");
}
finally
{
connection.ChiudiDatabase();
}
La connessione deve essere chiusa quando l'operazione è terminata. L'uso di using garantisce anche la chiamata a Dispose.
Stored procedure con parametri
using B.BData;
using System.Data;
connection.ClearParameter();
connection.AddParameter("@ID", 10);
DataTable systems = connection.ApriDT(
"BSP_sysSistemi_SELECT",
CommandType.StoredProcedure);
Prima di preparare una nuova operazione, chiamare ClearParameter per non riutilizzare accidentalmente i parametri dell'operazione precedente.
Transazione esplicita
using B.BData;
using System.Data;
connection.ApriDatabase();
connection.BeginTrans();
try
{
connection.ClearParameter();
connection.AddParameter("@Descrizione", "Nuovo sistema");
connection.ExecuteNonQuery("BSP_sysSistemi_INSERT", CommandType.StoredProcedure);
connection.CommitTrans();
}
catch
{
connection.RollBackTrans();
throw;
}
finally
{
connection.EndTrans();
connection.ChiudiDatabase();
}
Le classi generate da BStudio applicano questo stesso schema nei metodi Update, con rollback in caso di errore e chiusura nel blocco finally.
Funzione di supporto usata negli esempi
static BSettingDatabase GetDatabaseSetting()
{
return new BSettingDatabase
{
ConnectionString = "connection-string-letta-dalla-configurazione"
};
}
Inserimento massivo di una DataTable
BColumnBind[] mappings =
{
new BColumnBind("ExternalCode", "Codice"),
new BColumnBind("ExternalDescription", "Descrizione")
};
connection.InsertDTTimeout = 120;
bool inserted = connection.InsertDT(
source,
"sysSistemiImport",
mappings);
InsertDT usa il bulk copy di SQL Server e importa soltanto le righe Added. Controllare sempre il valore restituito. Per gli esempi completi con mapping, conservazione delle identity, timeout, gestione degli errori e transazione consultare BColumnBind - Esempi.
Esportazione in file delimitato
using B.BData;
using System.Data;
DataTable systems = connection.ApriDT(
"BSP_sysSistemi_SEARCH",
CommandType.StoredProcedure);
Exception? error = connection.ScriviFile(
systems,
@"C:\Export\systems.csv",
Separatore: ";",
DefaultEncoding: "UTF-8");
if (error != null)
{
throw error;
}
ScriviFile restituisce null quando l'operazione riesce oppure l'eccezione intercettata quando non può completare l'esportazione.
Questo overload scrive le righe senza intestazione. Se il file deve essere successivamente riletto dall'overload semplice di ApriDT, aggiungere una riga di intestazione oppure utilizzare l'overload di esportazione che consente di configurare WithHeader.
Importazione da file delimitato
DataTable? importedSystems = connection.ApriDT(
@"C:\Import\systems.csv",
Separatore: ";",
AutoDetectedEncoding: true,
DefaultEncoding: "UTF-8");
L'overload semplice considera la prima riga del file come intestazione delle colonne.
Questo overload legge file delimitati semplici: non interpreta automaticamente virgolette, separatori contenuti nei valori o regole CSV avanzate.
File delimitato già caricato in un BFile
using B.BData;
using B.BIO;
BFile file = new BFile(@"C:\Import\systems.csv");
DataTable? header = connection.ApriDT(
file,
Separatore: ";",
OnlyHeader: true,
AutoDetectedEncoding: true,
DefaultEncoding: "UTF-8");
DataTable? completeTable = connection.ApriDT(
file,
Separatore: ";",
OnlyHeader: false);
L'overload con BFile legge il contenuto binario disponibile in BFile.Content. Con OnlyHeader: true crea soltanto le colonne usando la prima riga; con false legge anche tutte le righe successive.
File con terminatore di record e tipi nell'header
Esempio di contenuto, con | come separatore e <EOR> come terminatore di record:
ID~Int32|Descrizione~String|DataCreazione~DateTime<EOR>
10|Sistema vendite|10/08/2026 14:30:00<EOR>
11|Sistema acquisti|11/08/2026 09:15:00<EOR>
DataTable? typedTable = connection.ApriDT(
@"C:\Import\systems.dat",
Separatore: "|",
EOF: "<EOR>",
WithTypeIntoHeader: true,
SeparatoreHeader: "~");
Con WithTypeIntoHeader: true, ogni colonna dell'header segue la forma Nome~Tipo. I tipi riconosciuti sono Boolean, Byte, Byte[], SmallInt, Int32, Int64, Double, Single, String e DateTime; un tipo assente o sconosciuto viene trattato come String.
Il terminatore EOF deve comparire anche dopo l'ultima riga, altrimenti quella riga non viene importata.
Tracciato posizionale o codificato
Per file a larghezza fissa, campi numerici con zeri iniziali o virgola virtuale, date in formato prestabilito, prefissi e posizioni definite, costruire un BCodificaTracciato e passarlo ad ApriDT:
using B.BData;
BCodificaTracciato layout = new BCodificaTracciato();
layout.AggiungiCampo(new BCodificaTracciatoCampo
{
NomeCampo = "Codice",
PosizioneCampo = 0,
LungCampo = 10
});
layout.AggiungiCampo(new BCodificaTracciatoCampo
{
NomeCampo = "Descrizione",
PosizioneCampo = 10,
LungCampo = 40
});
DataTable? decodedTable = connection.ApriDT(
@"C:\Import\systems-fixed.txt",
layout,
AutoDetectedEncoding: true,
DefaultEncoding: "UTF-8");
Le posizioni sono a base zero. Per ogni campo devono essere coerenti PosizioneCampo e LungCampo; per date e numeri configurare anche TipoDatoCampo, FormatoCampo, FormatoDataOra o NumeroDecimali secondo il tracciato reale.
