Добавление данных с помощью SqlDataAdapter.Fill

#c# #.net #datatable

#c# #.net #datatable

Вопрос:

Я повторяю цикл, идея заключается в том, что каждый раз, когда он проходит через цикл, к одному и тому же datatable добавляется больше строк. Я понял, что при использовании метода fill это будет иметь место. Однако в моем коде конечная таблица данных является результатом последнего цикла. Вот мой код:

Вызывающий метод

         // declare a new new datatable to hold the results of the query
        DataTable dtResults = new DataTable();

        foreach (OrgChartNode node in RadOrgChart1.GetAllNodes())
        {
            Label label1 = (Label)node.GroupItems[0].FindControl("Label1");
            foreach (OrgChartRenderedField rf1 in node.GroupItems[0].RenderedFields)
            {
                if (rf1.Label == "ibl")
                {
                    string[] iblWords = rf1.Text.Split(':');
                    string iblId = iblWords[0].Trim();

                    string[,] sqlParam01 =
                                {
                                    { "@document_id", iblId },
                                    { "@class_id", "123" }
                                };
                    dtResults = Helper.GetDataTablePrime(SQL_Default.SQL_Report, sqlParam01, dtResults);

                }

            }

            RadGrid2.DataSource = dtResults;
            RadGrid2.DataBind();
  

и вот метод GetDataTablePrime:

     public static DataTable GetDataTablePrime(string query, string[,] sqlParameters, DataTable dtContents)
    {
        String connString = "Data Source=*********************************";
        SqlDataAdapter adapter = new SqlDataAdapter();
        using (SqlConnection conn = new SqlConnection(connString))
        {
            adapter.SelectCommand = new SqlCommand(query, conn);

            // loop through adding parameters
            for (int i = 0; i <= sqlParameters.GetUpperBound(0); i  )
            {
                adapter.SelectCommand.Parameters.Add(new SqlParameter(sqlParameters[i, 0], sqlParameters[i, 1]));
            }
            adapter.Fill(dtContents);
            conn.Close();
        }
        return dtContents;
    }
  

Что-нибудь выглядит неуместно?

Комментарии:

1. Если вы посмотрите, код для подготовки всего для этого «вспомогательного» метода более сложный, более неясный и менее точный, чем прямое использование поставщика БД.

Ответ №1:

Не обновляйте адаптер данных при каждом вызове GetDataTablePrime . Используйте тот же экземпляр, что и вы dtResults .

Редактировать Этот ответ неверен. Он все равно работает, если вы каждый раз обновляете адаптер данных:

 using System;
using System.Data;
using System.Data.SqlClient;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add(new DataColumn("foo"));

            for (int i = 0; i < 3; i  )
            {
                dt = FillIt(dt);
            }

            for (int i = 0; i < dt.Rows.Count; i  )
            {
                Console.WriteLine(dt.Rows[i][0]);
            }

            Console.ReadKey();
        }

        private static DataTable FillIt(DataTable dtin)
        {
            SqlDataAdapter da = new SqlDataAdapter();
            SqlConnection cnxn = new SqlConnection("Data Source=(LocalDB)\MSSQLLocalDB;Initial Catalog=master;Integrated Security=True");
            SqlCommand cmd = new SqlCommand("SELECT 'bar' AS [foo];", cnxn);
            da.SelectCommand = cmd;

            da.Fill(dtin);
            return dtin;
        }
    }
}
  

Но вам не нужно возвращать таблицу данных. Это ссылочный тип, поэтому вы можете просто заполнить его.

 using System;
using System.Data;
using System.Data.SqlClient;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add(new DataColumn("foo"));

            for (int i = 0; i < 3; i  )
            {
                FillIt(dt);
            }

            for (int i = 0; i < dt.Rows.Count; i  )
            {
                Console.WriteLine(dt.Rows[i][0]);
            }

            Console.ReadKey();
        }

        private static void FillIt(DataTable dtin)
        {
            SqlDataAdapter da = new SqlDataAdapter();
            SqlConnection cnxn = new SqlConnection("Data Source=(LocalDB)\MSSQLLocalDB;Initial Catalog=master;Integrated Security=True");
            SqlCommand cmd = new SqlCommand("SELECT 'bar' AS [foo];", cnxn);
            da.SelectCommand = cmd;

            da.Fill(dtin);
        }
    }
}
  

Так что я не вижу ничего плохого в вашем коде в конце концов. Должно быть, что-то не показано.