Estou fazendo uma coisa básica em C # (MS VS2008) e tenho uma pergunta mais sobre design adequado do que código específico.
Estou criando uma tabela de dados e, em seguida, tentando carregar a tabela de dados de um datareader (que é baseado em um procedimento armazenado SQL). O que estou me perguntando é se a maneira mais eficiente de carregar a tabela de dados é fazer uma instrução while ou se existe uma maneira melhor.
Para mim, a única desvantagem é que tenho que digitar manualmente os campos que quero adicionar ao meu comando while, mas também não sei como automatizar isso de qualquer maneira, já que não quero todos os campos do SP, apenas selecione alguns , mas isso não é um grande negócio aos meus olhos.
Incluí trechos de código abaixo da totalidade do que faço, embora para mim o código em si não seja notável ou mesmo o que estou perguntando. Ainda me perguntando sobre minha metodologia, irei implorar por ajuda de código mais tarde se minha estratégia estiver errada / ineficiente.
var dtWriteoffUpload = new DataTable();
dtWriteoffUpload.Columns.Add("Unit");
dtWriteoffUpload.Columns.Add("Year");
dtWriteoffUpload.Columns.Add("Period");
dtWriteoffUpload.Columns.Add("Acct");
dtWriteoffUpload.Columns.Add("Descr");
dtWriteoffUpload.Columns.Add("DEFERRAL_TYPE");
dtWriteoffUpload.Columns.Add("NDC_Indicator");
dtWriteoffUpload.Columns.Add("Mgmt Cd");
dtWriteoffUpload.Columns.Add("Prod");
dtWriteoffUpload.Columns.Add("Node");
dtWriteoffUpload.Columns.Add("Curve_Family");
dtWriteoffUpload.Columns.Add("Sum Amount");
dtWriteoffUpload.Columns.Add("Base Curr");
dtWriteoffUpload.Columns.Add("Ledger");
cmd = util.SqlConn.CreateCommand();
cmd.CommandTimeout = 1000;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "proc_writeoff_data_details";
cmd.Parameters.Add("@whoAmI", SqlDbType.VarChar).Value =
WindowsIdentity.GetCurrent().Name;
cmd.Parameters.Add("@parmEndDateKey", SqlDbType.VarChar).Value = myMostRecentActualDate;
cmd.Parameters.Add("@countrykeys", SqlDbType.VarChar).Value = myCountryKey;
cmd.Parameters.Add("@nodekeys", SqlDbType.VarChar).Value = "1,2";
break;
dr = cmd.ExecuteReader();
while (dr.Read())
{
dtWriteoffUpload.Rows.Add(dr["country name"].ToString(), dr["country key"].ToString());
}
Respostas:
Você pode carregar um
DataTable
diretamente de um leitor de dados usando oLoad()
método que aceita umIDataReader
.fonte
Por favor, verifique o código abaixo. Ele será convertido automaticamente em DataTable
fonte
dt.Load(reader)
também nem sempre funciona - eu recebo aquelesObject reference not set to an instance of an object
erros incômodos , provavelmente quando não recebo nenhuma linha de volta. Um manual como este é útil. Eu tentei e tive que me livrar dessascolumn.
linhas nodtSchema
foreach
loop porque dizia que era um elenco ilegal parabool
on(bool)drow["IsUnique"]
. Eu não precisava deles, obter os nomes das colunas para preencher o novoDataTable
é o suficiente. Isso me ajudou a superar umds.Fill(adapter)
problema com o qual eu não conseguia carregar uma mesa grandeSELECT * FROM MyTable
.if (!dr.IsDBNull(i))
como a próxima coisa dentro dessefor
loop. Você então faz suasdataRow
coisas. Mas então você precisa de umelse
sobre isso, caso encontre um nulo. Se o fizer, terá de descobrir o tipo de coluna que está a adicionar e atribuir o nulo de acordo (ou seja, pode atribuirString.Empty
se é do tipoSystem.String
, mas tem de atribuir0
se éSystem.Int16
(campo booleano) ouSystem.Decimal
.Se você estiver tentando carregar um
DataTable
, aproveite oSqlDataAdapter
:Você nem precisa definir as colunas. Basta criar o
DataTable
eFill
isso.Aqui,
cString
está sua string de conexão esql
é o comando de procedimento armazenado.fonte
SqlDataReader
e lendo-os usando um loop pelos campos.Como Sagi afirmou em sua resposta, DataTable.Load é uma boa solução. Se você estiver tentando carregar várias tabelas de um único leitor, não precisa chamar DataReader.NextResult. O método DataTable.Load também avança o leitor para o próximo conjunto de resultados (se houver).
fonte
Também examinei isso e, depois de comparar o método SqlDataAdapter.Fill com as funções SqlDataReader.Load, descobri que o método SqlDataAdapter.Fill é mais de duas vezes mais rápido do que os conjuntos de resultados que estou usando
Código usado:
Resultados:
Para problemas de desempenho, usar o método SqlDataAdapter.Fill é muito mais eficiente. Então, a menos que você queira atirar no próprio pé, use isso. Ele funciona mais rápido para conjuntos de dados pequenos e grandes.
fonte