Получите текущий идентификатор в GridView и вставьте его как идентификатор в другую таблицу при нажатии кнопки

У меня есть таблица Documents и GridView, в которой я отображаю некоторую информацию. Внутри ItemTemplate я поместил кнопки в качестве рейтинговой системы. Что я хочу сделать, так это получить DocumentID из таблицы Documents и использовать его в качестве идентификатора в таблице RatingTable с DocumentID в качестве первичного и внешнего ключа и рейтингом как tinyint.

Вот код для gridview:

<asp:GridView ID="SearchView" runat="server" AutoGenerateColumns="false" OnSelectedIndexChanged="SearchView_SelectedIndexChanged" ShowHeaderWhenEmpty="true" EmptyDataText="Ingen oppføringer">
        <Columns>
            <asp:BoundField DataField="FileName" HeaderText="Filnavn" />
            <asp:BoundField DataField="ReportCount" HeaderText="Antall rapporteringer" />
            <asp:BoundField DataField="Tags" HeaderText="Tags" />
            <asp:BoundField DataField="CourseCode" HeaderText="Fagkode" />
            <asp:TemplateField HeaderText="Rating">
                <ItemTemplate>
                    <asp:ImageButton class="myButtonLink" ImageUrl="~/Images/empty_star.png" ID="rate1" runat="server" OnClick="rate1_Click"/>
                    <asp:ImageButton class="myButtonLink" ImageUrl="~/Images/empty_star.png" ID="rate2" runat="server" OnClick="rate2_Click"/>
                    <asp:ImageButton class="myButtonLink" ImageUrl="~/Images/empty_star.png" ID="rate3" runat="server" OnClick="rate3_Click"/>
                    <asp:ImageButton class="myButtonLink" ImageUrl="~/Images/empty_star.png" ID="rate4" runat="server" OnClick="rate4_Click"/>
                    <asp:ImageButton class="myButtonLink" ImageUrl="~/Images/empty_star.png" ID="rate5" runat="server" OnClick="rate5_Click"/>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField ItemStyle-HorizontalAlign="Center" HeaderText="Nedlastingslink">
                <ItemTemplate>
                    <asp:LinkButton ID="downloadbutton" runat="server" Text="Last ned" OnClick="Download_Click"
                        CommandArgument='<%# Eval("FileName") %>'></asp:LinkButton>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField ItemStyle-HorizontalAlign="Center" HeaderText="Rapporter" ItemStyle-Font-Size="Small">
                <ItemTemplate>
                    <asp:LinkButton ID="reportbutton" runat="server" Text="Rapporter dokument" OnClick="Report_Click"></asp:LinkButton>
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>

Вот код, в котором я пытаюсь вставить значение рейтинга в RatingTable:

protected void updaterating(int rating)
    {
        //string value = SearchView.SelectedDataKey.Value.ToString();
        using (SqlConnection con = new SqlConnection(connectionstring))
        {
            using (SqlCommand cmd = new SqlCommand("INSERT INTO RatingTable (DocumentID, Rating) VALUES(@DocumentID, @Rating)"))
            {
                using (SqlDataAdapter sda = new SqlDataAdapter())
                {
                    cmd.CommandType = CommandType.Text;
                    //cmd.Parameters.AddWithValue("@DocumentID", value);
                    cmd.Parameters.AddWithValue("@Rating", rating);
                    cmd.Connection = con;
                    con.Open();
                    cmd.ExecuteNonQuery();
                    con.Close();
                }
            }
        }
        Response.Redirect(Request.Url.AbsoluteUri);
    }

    protected void rate1_Click(object sender, ImageClickEventArgs e)
    {
        updaterating(1);
    }

    protected void rate2_Click(object sender, ImageClickEventArgs e)
    {
        updaterating(2);
    }

    protected void rate3_Click(object sender, ImageClickEventArgs e)
    {
        updaterating(3);
    }

    protected void rate4_Click(object sender, ImageClickEventArgs e)
    {
        updaterating(4);
    }

    protected void rate5_Click(object sender, ImageClickEventArgs e)
    {
        updaterating(5);
    }

Вот что нравится инструментам RatingTable:

[RatingTable] (
[DocumentID] INT     NOT NULL,
[Rating]     TINYINT NOT NULL,
PRIMARY KEY CLUSTERED ([DocumentID] ASC),
CONSTRAINT [FK_RatingTable_Documents] FOREIGN KEY ([DocumentID]) REFERENCES [dbo].[Documents] ([DocumentId])

);

Что я пытаюсь сделать, так это когда я нажимаю одну из кнопок ImageButtons в поле TemplateField «Рейтинг», я хочу, чтобы он получил текущий DocumentID для строки, в которой я нахожусь, и использовал это, чтобы вставить его в RatingTable в качестве основного ключ со значением нажатой звезды. В функции обновления в приведенном ниже коде я закомментировал несколько строк, в которых я пытался использовать DataKeyNames в GridView для получения идентификатора, но это дает пустой GridView.

 if (!IsPostBack)
        {
            SearchView.DataKeyNames = new string[]{"DocumentID"};
            BindGrid();
        }

Я добавил это, чтобы попытаться получить DataKeyNames прямо перед привязкой сетки, но GridView все еще пуст.

Я также изменил строковое значение, потому что использовал неправильный атрибут:

protected void updaterating(int rating)
    {
        string value = SearchView.DataKeyNames.ToString();
        using (SqlConnection con = new SqlConnection(connectionstring))
        {
            using (SqlCommand cmd = new SqlCommand("INSERT INTO RatingTable (DocumentID, Rating) VALUES(@DocumentID, @Rating)"))
            {
                using (SqlDataAdapter sda = new SqlDataAdapter())
                {
                    cmd.CommandType = CommandType.Text;
                    cmd.Parameters.AddWithValue("@DocumentID", value);
                    cmd.Parameters.AddWithValue("@Rating", rating);
                    cmd.Connection = con;
                    con.Open();
                    cmd.ExecuteNonQuery();
                    con.Close();
                }
            }
        }
        Response.Redirect(Request.Url.AbsoluteUri);
    }

Любая помощь высоко ценится!


person earlyend    schedule 11.05.2015    source источник
comment
На самом деле вы не говорите нам, какая часть вашего кода не работает должным образом и в чем именно заключается ваша проблема.   -  person Christina    schedule 11.05.2015
comment
Я пытался использовать строковое значение в коде позади и AddWithValue для DocumentID, используя DataKeyNames в качестве DocumentID в GridView, но тогда GridView ничего не отображал.   -  person earlyend    schedule 11.05.2015
comment
Мне жаль. Когда я нажимаю одну из кнопок, я получаю SQLException, потому что @DocumentID не объявлен. Но я не уверен, как получить DocumentID и вставить его.   -  person earlyend    schedule 11.05.2015
comment
Не могли бы вы отредактировать свой вопрос и добавить эти детали, а также точное исключение, которое вы получаете?   -  person Christina    schedule 11.05.2015


Ответы (1)


Вам нужно добавить DataKeyName в свой GridView. Если я правильно понял вопрос, это будет DocumentID.

<asp:GridView ID="SearchView" runat="server" 
    AutoGenerateColumns="false" 
    OnSelectedIndexChanged="SearchView_SelectedIndexChanged" 
    ShowHeaderWhenEmpty="true" 
    EmptyDataText="Ingen oppføringer"
    DataKeyNames="DocumentID">

Затем, когда вы запускаете эту строку:

string value = SearchView.SelectedDataKey.Value.ToString();

GridView действительно знает, что такое DataKey. Поскольку вы используете SelectedDataKey, также должна быть выбрана строка, чтобы это свойство имело значение.

Чтобы найти индекс строки, когда она не выбрана, вам нужно найти строку, в которой содержится нажатая кнопка.

protected void rate1_Click(object sender, ImageClickEventArgs e)
{
    ImageButton rate1 = (ImageButton)sender;
    GridViewRow row = (GridViewRow)rate1.NamingContainer;
    DataKey key = SearchView.DataKeys[row.DataItemIndex];

    // Now you have your key, use it how you'd like.
    // This may mean passing it as another variable
    // to your updaterating method.

    updaterating(1);
}
person j.f.    schedule 11.05.2015
comment
Когда у меня были DataKeyNames в GridView, GridView был пуст. Я также изменил SelectedDataKey на SearchView.DataKeyNames.ToString(); - person earlyend; 11.05.2015
comment
Использование SearchView.DataKeyNames.ToString(); тоже не сработает, потому что DataKeyNames — это массив строк. Вам нужно найти индекс вашей строки в массиве DataKeyNames, чтобы получить его значение. - person j.f.; 11.05.2015
comment
Добавление DataKeyName не приведет к привязке данных к GridView. Если DataKeyName не существует в источнике данных, вы получите сообщение об ошибке. - person j.f.; 11.05.2015
comment
Я понимаю. Любые предложения о том, как найти индекс? Я не очень опытен в использовании ASP.Net. - person earlyend; 11.05.2015
comment
Я добавил строковый аргумент в функцию updaterating. Но строка DataKey key = SearchView.DataKeyNames[row.DataItemIndex]; выдает ошибку: невозможно неявно преобразовать тип "строка" в "System.Web.UI.WebControls.DataKey" - person earlyend; 11.05.2015
comment
Извините, я хотел использовать DataKeys, а не DataKeyNames. Смотрите мою правку. - person j.f.; 11.05.2015
comment
Это сработало, используя key.Value и приведя его к типу int, потому что DocumentID имеет тип int. Большое тебе спасибо! Кстати, я обнаружил ошибку, почему мой GridView был пустым при использовании DataKeyNames; Я забыл выбрать DocumentID... - person earlyend; 11.05.2015
comment
Пожалуйста! Рад, что вы смогли заставить его работать. - person j.f.; 11.05.2015