SqlCommand.ExecuteReader и прохождение первой строки - PullRequest
1 голос
/ 26 марта 2012

Я довольно новичок в ASP.NET и в качестве самостоятельного задания я должен создать простой блог.Это почти закончено, но я столкнулся с проблемой.Как вы можете видеть из кода, я сначала использую запрос, чтобы вернуть количество записей в блоге из моей базы данных сервера SQL.Затем цикл for считывает заголовки, даты и текстовое содержимое из всех строк и создает HTML-элемент div, в который он загружает их. Прекрасно работает, за исключением одной вещи: ExecuteScalar () читает только первую строку, которая будет возвращать одно и то же значение для каждой итерации, в результате чего все записи блога будут одинаковыми.

Мне нуженспособ для читателя двигаться с каждой итерации.Я подумал о том, чтобы сделать SQLbulkcopy в другую таблицу, из которой я могу затем удалить верхнюю строку в цикле for, но похоже, что это замедлит страницу на значительное количество, если это будет сделано для каждой Page_Load.

string SQLreadTitle = "Select BLOG.BlogTitle from BLOG order by BlogID DESC";
string SQLreadDate = "Select BLOG.BlogDate from BLOG order by BlogID DESC";
string SQLreadText = "Select BLOG.BlogText from BLOG order by BlogID DESC";
string SQLcountIDs = "Select count(BlogID) from BLOG";

protected void Page_Load(object sender, EventArgs e)
{

    int i;
    SqlConnection con = new SqlConnection(cnString);
    con.Open();

    SqlCommand countIDs = new SqlCommand(SQLcountIDs, con);
    int count = Convert.ToInt32(countIDs.ExecuteScalar());



    for (i = 0; i < count; i++)
    {
        SqlCommand readTitle = new SqlCommand(SQLreadTitle, con);
        string titleString = readTitle.ExecuteScalar().ToString();
        SqlCommand readDate = new SqlCommand(SQLreadDate, con);
        string dateString = readDate.ExecuteScalar().ToString();
        SqlCommand readText = new SqlCommand(SQLreadText, con);
        string textString = readText.ExecuteScalar().ToString();



        System.Web.UI.HtmlControls.HtmlGenericControl dynDiv =
        new System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
        dynDiv.ID = "BlogPost";
        dynDiv.InnerHtml = "<div id=\"BlogTitle\">" + 
            titleString + "</div><br /><div id=\"BlogDate\">"
            + dateString + "</div><br /><br /><div id=\"BlogText\">" 
            + textString + "</div>";
        Label1.Controls.Add(dynDiv);


    }
    con.Close();
}

Заранее спасибо!

Ответы [ 3 ]

5 голосов
/ 26 марта 2012

Вы делаете жизнь слишком тяжелой для себя.У вас должен быть один оператор select, а затем читать каждую возвращаемую строку.

    string SQL = "Select BLOG.BlogTitle, BLOG.BlogDate, BLOG.BlogText from BLOG order by BlogID DESC";
    // Positions of the columns you are reading
    const int TITLE_ORDINAL = 0;
    const int DATE_ORDINAL = 1;
    const int TEXT_ORDINAL = 2;

    protected void Page_Load(object sender, EventArgs e)
    {
        using (var con = new SqlConnection(cnString))
        {
            con.Open();
            try
            {
                using (var oCommand = new SqlCommand(SQL, con))
                {
                    using (var oReader = oCommand.ExecuteReader())
                    {
                        while (oReader.Read())
                        {
                            var dynDiv = new System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
                            dynDiv.ID = "BlogPost";
                            dynDiv.InnerHtml = "<div id=\"BlogTitle\">" +
                                oReader.GetString(TITLE_ORDINAL) + "</div><br /><div id=\"BlogDate\">"
                                + oReader.GetString(DATE_ORDINAL) + "</div><br /><br /><div id=\"BlogText\">"
                                + oReader.GetString(TEXT_ORDINAL) + "</div>";
                            Label1.Controls.Add(dynDiv);
                        }
                    }
                }
            } finally {
                con.Close();
            }
        }
    }
1 голос
/ 26 марта 2012

Я думаю, что вы прочитали немного больше об ADO.NET, так как у вас есть неправильные понятия. SqlCommand.ExecuteScalar используется для получения одного значения из базы данных, а не для получения набора данных.

Вам не нужно получать количество элементов для итерации по набору записей. Используя SqlCommand.ExecuteReader , вы можете получить все необходимые данные в одном запросе. Здесь у вас есть пример кода, которому вы можете следовать

string sqlQuery = "Select * from BLOG order by BlogID DESC";
using (SqlConnection con = new SqlConnection(cnString))
{
    con.Open();
    using (SqlCommand cmd = new SqlCommand(sqlQuery, con))
    {
        using (SqlDataReader dr = cmd.ExecuteReader())
        {
            while (dr.Read())
            {
                System.Web.UI.HtmlControls.HtmlGenericControl dynDiv =
                new System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
                dynDiv.ID = "BlogPost";
                dynDiv.InnerHtml = "<div id=\"BlogTitle\">" +
                    dr["BlogTitle"] + "</div><br /><div id=\"BlogDate\">"
                    + dr["BlogDate"].ToString() + "</div><br /><br /><div id=\"BlogText\">"
                    + dr["BlogText"] + "</div>";
                Label1.Controls.Add(dynDiv);
            }
        }
    }
}

Здесь у вас есть статья MSDN, которая может помочь вам понять, как использовать SqlDataReader

0 голосов
/ 26 марта 2012

ExecuteScalar здесь не то, что вам нужно, и вам не нужен счетчик. Прочитайте здесь об адаптере данных. После вызова метода Fill таблица данных thr содержит все содержимое базы данных и может быть перебрана. Вы можете прочитать о таблице данных класса здесь .

Простой пример итерации:

DataTable tbl = new DataTable();

foreach (DataRow row in tbl.Rows)
{
    foreach (DataColumn col in tbl.Columns)
    {
        object cellData = row[col];
    }
}
...