Nella mia applicazione ho bisogno di visualizzare un elenco di record restituiti da diverse stored procedure. Ogni procedura di archiviazione restituisce diversi tipi di record (ovvero il numero di colonne e il tipo di colonna sono diversi).Funzione C# per restituire oggetti/entità generici
Il mio pensiero originale era quello di creare una classe per ogni tipo di record e creare una funzione che eseguisse la stored procedure corrispondente e restituisse l'elenco < MyCustomClass>. Qualcosa di simile a questo:
public class MyCustomClass1
{
public int Col1 { get; set; } //In reality the columns are NOT called Col1 and Col1 but have proper names
public int Col2 { get; set; }
}
public static List<MyCustomClass1> GetDataForReport1(int Param1)
{
List<MyCustomClass1> output = new List<MyCustomClass1>();
using (SqlConnection cn = new SqlConnection("MyConnectionString"))
using (SqlCommand cmd = new SqlCommand("MyProcNameForReport1", cn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@Param1", SqlDbType.Int).Value = Param1;
SqlDataReader rdr=cmd.ExecuteReader();
int Col1_Ordinal = rdr.GetOrdinal("Col1");
int Col2_Ordinal = rdr.GetOrdinal("Col2");
while (rdr.Read())
{
output.Add(new MyCustomClass1
{
Col1 = rdr.GetSqlInt32(Col1_Ordinal).Value,
Col2 = rdr.GetSqlInt32(Col2_Ordinal).Value
});
}
rdr.Close();
}
return output;
}
Questo funziona bene, ma come non ho bisogno di manipolare i record nel mio codice cliente (ho solo bisogno di legarli ad un controllo grafico nel mio livello di applicazione) in realtà non ha senso farlo in questo modo, in quanto finirei con un sacco di classi personalizzate che non utilizzerei in realtà. Ho trovato questo, che fa il trucco:
public static DataTable GetDataForReport1(int Param1)
{
DataTable output = new DataTable();
using (SqlConnection cn = new SqlConnection("MyConnectionString"))
using (SqlCommand cmd = new SqlCommand("MyProcNameForReport1", cn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@Param1", SqlDbType.Int).Value = Param1;
output.Load(cmd.ExecuteReader());
}
return output;
}
Ciò restituisce un DataTable cui posso associare a qualsiasi controllo che uso nel mio livello di applicazione. Mi chiedo se l'utilizzo di un DataTable sia davvero necessario.
Non potrei restituire un elenco di oggetti creata usando classi anonime:
public static List<object> GetDataForReport1(int Param1)
{
List<object> output = new List<object>();
using (SqlConnection cn = new SqlConnection("MyConnectionString"))
using (SqlCommand cmd = new SqlCommand("MyProcNameForReport1", cn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@Param1", SqlDbType.Int).Value = Param1;
SqlDataReader rdr=cmd.ExecuteReader();
int Col1_Ordinal = rdr.GetOrdinal("Col1");
int Col2_Ordinal = rdr.GetOrdinal("Col2");
while (rdr.Read())
{
output.Add(new
{
Col1 = rdr.GetSqlInt32(Col1_Ordinal).Value,
Col2 = rdr.GetSqlInt32(Col2_Ordinal).Value
});
}
rdr.Close();
}
return output;
}
altre idee? Fondamentalmente voglio solo che la funzione restituisca "qualcosa" che posso associare a un controllo grafico e preferisco non dover creare classi personalizzate in quanto non verrebbero effettivamente utilizzate. Quale sarebbe l'approccio migliore?
btw, la migliore procedura per SqlDataReader è il seguente stile di utilizzo: using (var rdr = cmd.ExecuteReader() {while (rdr.Read() {..}} - quindi verrà chiuso (disposto) automaticamente – abatishchev
Ben individuato ... – Anthony