Я делаю базовые вещи на C # (MS VS2008), и у меня вопрос больше о правильном дизайне, чем о конкретном коде.
Я создаю базу данных, а затем пытаюсь загрузить ее из устройства чтения данных (которое основано на хранимой процедуре SQL). Что мне интересно, так это то, является ли наиболее эффективным способом загрузки таблицы данных выполнение оператора while или есть лучший способ.
Для меня единственный недостаток заключается в том, что мне нужно вручную вводить поля, которые я хочу добавить в свой оператор while, но я также не знаю, как это автоматизировать, поскольку я не хочу, чтобы все поля из SP просто выбирали их. , но в моих глазах это не имеет большого значения.
Я включил фрагменты кода ниже всего того, что я делаю, хотя для меня сам код не примечателен и даже не то, о чем я спрашиваю. Больше того, интересуясь моей методологией, я буду приставать к помощи кода позже, если моя стратегия неправильная / неэффективная.
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());
}
Ответы:
Вы можете загрузить
DataTable
прямо из средства чтения данных, используяLoad()
метод, который принимаетIDataReader
.источник
Пожалуйста, проверьте приведенный ниже код. Автоматически он будет преобразован как DataTable
источник
dt.Load(reader)
также не всегда работает - я бы получил эти надоедливыеObject reference not set to an instance of an object
ошибки, вероятно, когда я не получил ни одной строки обратно. Что-то вроде этого руководства пригодится. Я попробовал и мне пришлось избавиться от этихcolumn.
строк вdtSchema
foreach
цикле, потому что он сказал, что это незаконное приведение кbool
включению(bool)drow["IsUnique"]
. Они мне не понадобились, достаточно получить имена столбцов, чтобы заполнить новыеDataTable
. Это помогло мне преодолетьds.Fill(adapter)
проблему, из-за которой я не мог загрузить большую таблицуSELECT * FROM MyTable
.if (!dr.IsDBNull(i))
как следующее в этомfor
цикле. Затем вы делаете свое делоdataRow
. Но тогда вам понадобится этоelse
, если вы найдете нуль. Если вы это сделаете, вам нужно выяснить тип добавляемого столбца и соответствующим образом присвоить значение null (то есть вы можете назначить,String.Empty
если он имеет типSystem.String
, но вам нужно назначить,0
если этоSystem.Int16
(логическое поле) илиSystem.Decimal
.Если вы пытаетесь загрузить
DataTable
, используйтеSqlDataAdapter
вместо этого:Вам даже не нужно определять столбцы. Просто создайте
DataTable
иFill
это.Вот
cString
ваша строка подключения иsql
команда хранимой процедуры.источник
SqlDataReader
и читать их, используя цикл по полям.Как заявил Саги в своем ответе, DataTable.Load - хорошее решение. Если вы пытаетесь загрузить несколько таблиц из одного считывателя, вам не нужно вызывать DataReader.NextResult. Метод DataTable.Load также перемещает читателя к следующему набору результатов (если есть).
источник
Я тоже изучил это, и после сравнения метода SqlDataAdapter.Fill с функциями SqlDataReader.Load я обнаружил, что метод SqlDataAdapter.Fill более чем в два раза быстрее с наборами результатов, которые я использовал
Используемый код:
Полученные результаты:
Для проблем с производительностью использование метода SqlDataAdapter.Fill намного эффективнее. Так что, если вы не хотите выстрелить себе в ногу, используйте это. Он работает быстрее для небольших и больших наборов данных.
источник