Updating Database through edits to WPF Datagrid

旧城冷巷雨未停 提交于 2020-08-26 07:10:33

问题


I have seen a ton of write ups on this and yet cannot get this to work. I have a window in my C# WPF application that, on load, successfully fills a datatable based on a pre-defineds query (altered by user selections from previous window)

The Fill logic is here:

private void FillDataGrid()
    {
        string ConString = ConfigurationManager.ConnectionStrings["CONN"].ConnectionString;
        string CmdString = string.Empty;
        using (SqlConnection con = new SqlConnection(ConString))
        {
            CmdString = $@"select PGCL.Client_Name, PGG.Guarantee_Title, PGG.Guarantee_Desc_Org, PGGM.Target, PGG.Timing_Measurement, PGP.Month, PGP.Year, PGP.Quarter, PGP.Numerator, PGP.Denominator, PGP.Performance_Percent, PGP.Achieved_Flag, PGP.Performance_ID
                            from PGG
                                inner join PGC on PGC.Contract_ID = PGG.Contract_ID
                                inner join PGCL on PGCL.Client_ID = PGC.Contract_ID
                                inner join PGGM on PGGM.Guarantee_ID = PGG.Guarantee_ID
                                inner join PGP on PGP.Guarantee_ID = PGG.Guarantee_ID
                                Where PGP.Month = {this.monthNum.ToString()} and PGP.year = {this.yearNum.ToString()}
                                    and PGC.Active_Flag = 'y'
                                    and PGG.Department_Responsible_ID = {this.deptID.ToString()}
                                Order by Client_Name, Guarantee_Order asc";

            SqlCommand cmd = new SqlCommand(CmdString, con);
            SqlDataAdapter sda = new SqlDataAdapter(cmd);
            DataTable dt = new DataTable("PG");

            sda.Fill(dt);
            DGPG.ItemsSource = dt.DefaultView;

        }
    }

This portion works perfectly.

I have 5 columns in the PGP (aliased from above) table that I want to dynamically write values (in a few steps) to based on user input at the close of the window (with a prompt to save). What method would be recommended for doing this?

i.e.: if a user entered the value '5' for for Numerator on row 5 and '7' for denominator on row 10, i want the following to happen:

1) using the PGP.ID, insert into the PGP_History table (for historical logs of changes) 2) UPDATE PGP table values accordingly.

I would greatly appreciate it if someone could get me going in this direction?

Thank you, Wes

EDIT

I think I have made some progress but am stuck on the below, now:

       private void FillDataGrid()
    {
        string ConString = ConfigurationManager.ConnectionStrings["CONN"].ConnectionString;
        string CmdString = string.Empty;
        using (SqlConnection con = new SqlConnection(ConString))
        {
            CmdString = $@"select PGCL.Client_Name, PGG.Guarantee_Title, PGG.Guarantee_Desc_Org, PGGM.Target, PGG.Timing_Measurement, PGP.Month, PGP.Year, PGP.Quarter, PGP.Numerator, PGP.Denominator, PGP.Performance_Percent, PGP.Achieved_Flag, PGP.Performance_ID
                            from PGG
                                inner join PGC on PGC.Contract_ID = PGG.Contract_ID
                                inner join PGCL on PGCL.Client_ID = PGC.Contract_ID
                                inner join PGGM on PGGM.Guarantee_ID = PGG.Guarantee_ID
                                inner join PGP on PGP.Guarantee_ID = PGG.Guarantee_ID
                                Where PGP.Month = {this.monthNum.ToString()} and PGP.year = {this.yearNum.ToString()}
                                    and PGC.Active_Flag = 'y'
                                    and PGG.Department_Responsible_ID = {this.deptID.ToString()}
                                Order by Client_Name, Guarantee_Order asc";

            SqlCommand cmd = new SqlCommand(CmdString, con);
            SqlDataAdapter sda = new SqlDataAdapter(cmd);
            DataTable dt = new DataTable("PG");

            sda.Fill(dt);
            DGPerformanceGuarantees.ItemsSource = dt.DefaultView;
        }
    }

    private void Commit_Updates_Click(object sender, RoutedEventArgs e)
    {
        string ConString = ConfigurationManager.ConnectionStrings["CONN"].ConnectionString;
        //string CmdString = string.Empty;
        using (SqlConnection con = new SqlConnection(ConString))
        {
            //Update Logic
            SqlCommand update = new SqlCommand("UPDATE PGP SET PGP.NUMERATOR = @Numerator, DENOMINATOR = @Denominator, PERFORMANCE_PERCENT = @Percent, ACHIEVED_FLAG = '@Achieved' WHERE PERFORMANCE_ID = @Performance_ID", con);
            update.Parameters.Add(new SqlParameter("@Numerator", SqlDbType.Int, 5, "NUMERATOR"));
            update.Parameters.Add(new SqlParameter("@Denominator", SqlDbType.Int, 5, "DENOMINATOR"));
            update.Parameters.Add(new SqlParameter("@Percent", SqlDbType.Decimal, 18, "PERFORMANCE_PERCENT"));
                update.Parameters["@Percent"].Precision = 18;
                update.Parameters["@Percent"].Scale = 2;
            update.Parameters.Add(new SqlParameter("@Achieved", SqlDbType.NVarChar, 1, "ACHIEVED_FLAG"));
            update.Parameters.Add(new SqlParameter("@Performance_ID", SqlDbType.Int, 5, "Performance_ID"));

            sda.UpdateCommand = update;
            sda.Update(dt);
        }

        FillDataGrid();
    }

I added a button to trigger the update to occur. Obviously this does not compile because the SQL Data Adapter (sda) is does not exist in the context of the button handler.

What can I do to resolve this?


回答1:


Well there's a lot of ways to skin this cat.

If you wanted to do an update every time a cell is changed, I would subscribe to the DataGrid's CellEditEnding event which will basically inform you whenever a change to the cell has been made and committed by the user. (Check the DataGridCellEditEndingEventArgs argument to find out which column and cell were actually edited). With that, you can compose a targeted UPDATE statement and only update the cell that changed.

However, it sounds like you want to do a bulk update when the window closes. In that case, DataTable will track changes made to the data via the DataGrid given that you assigned it as the ItemsSource. When you're ready to commit changes, use DataTable.GetChanges to get a new DataTable with just the changed rows since the last time DataDatable.AcceptChanges was called. Perform your update (use SqlDataAdapter again this time. See the Update method.) This has the advantage of handling all updates and deletions in a single operation. One disadvantage is that - I believe - every column of the row is going to be updated, so this increases the amount of information that is transmitted to the database server with each update. In any event, then when your update is complete, call DataTable.AcceptChanges.

That should get you on the right track. Hope this helps.



来源:https://stackoverflow.com/questions/39884384/updating-database-through-edits-to-wpf-datagrid

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!