Беды связывания данных - PullRequest
       10

Беды связывания данных

7 голосов
/ 16 февраля 2010

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

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

Если я добавлю строки в базовую таблицу данных, когда таблица данных будет сохранена, строки будут продублированы, возможно потому, что источник привязки каким-то образом получил копию и вставил ее также.

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

Позвольте мне объяснить, какие у меня настройки:

У меня есть база данных с двумя таблицами: CashReceiptTable и CashReceiptItemsTable

CashReceiptItemsTable содержит FK для CashReceiptTable.

Форма позволяет пользователям добавлять и изменять две таблицы.

Когда пользователь вводит новую кассовую квитанцию, идентификатор кассовой квитанции равен -1, а FK в cashReceiptitemstable равен -1. Когда база данных сохранена, идентификатор cashReceipt обновляется, и мне приходится вручную обновлять FK cashreceiptitem.

Вот проблемы:

Когда я пытаюсь обновить CashReceiptID (FK) в более чем одной строке в источнике привязки cashreceiteitems, первая строка обновляется и исчезает (поскольку она отфильтрована), а другие строки удаляются, и я больше не могу получить к ним доступ.

Понятия не имею, почему, я еще не обновил фильтр, поэтому они все еще должны быть там, но попытка доступа к ним выдает исключение RowNotInTableException.

Я справился с обходом, которое копирует строки в источнике привязки в массив в памяти, удаляет первую строку в источнике привязки (все остальные строки просто исчезают), обновляет FK строки и повторно вставляет их в источник привязки и сохраните таблицу.

Это работает хорошо, но почему исчезают строки?

У меня также есть еще одна небольшая проблема. Когда CashReceiptsTable пуст и я добавляю в него новую строку, если я добавляю более одной строки в CashReceiptsItemTable, это вызывает проблемы. При ручном добавлении элементов в источник привязки добавление новой строки всплывает в предыдущей строке и помещает ее в таблицу данных. Это скрывает его от моей процедуры обновления FK и теряется, а также удаляет его из DataGridView.

Это только делает это, когда я добавляю первую строку в CashReceiptsTable. Почему это происходит, и как я могу это исправить?

Я публикую свой код, который заполняет его здесь:

        private void autopopulate(decimal totalPayment) {
            //remove old rows
            for (int i = 0; i < tblCashReceiptsApplyToBindingSource.List.Count; i++) {
                DataRowView viewRow = tblCashReceiptsApplyToBindingSource.List[i] as DataRowView;
                RentalEaseDataSet.tblCashReceiptsApplyToRow row = viewRow.Row as RentalEaseDataSet.tblCashReceiptsApplyToRow;

                if (row.CashReceiptsID == this.ReceiptID) {
                    tblCashReceiptsApplyToBindingSource.List.Remove(viewRow);
                    i--;
                }
            }

            decimal payment = totalPayment;

            //look for an exact amount
            foreach (DataGridViewRow dueRow in dataViewDueRO.Rows) {
                decimal due = -1 * (Decimal)dueRow.Cells[Due.Index].Value;
                if (due == payment) {
                    String charge = (String)dueRow.Cells[Description.Index].Value;
                    int chargeID = ManageCheckbooks.findTransactionID(charge);

                    tblCashReceiptsApplyToBindingSource.AddNew();

                    RentalEaseDataSet.tblCashReceiptsApplyToRow row = ((DataRowView)tblCashReceiptsApplyToBindingSource.Current).Row as RentalEaseDataSet.tblCashReceiptsApplyToRow;
                    row.CashReceiptsID = this.ReceiptID;
                    row.ApplyTo = chargeID;

                    row.Paid = payment; //convert to positive

                    payment = 0;
                    break;
                }
            }

            //if the exact amount was found, payment will = 0, and this will do nothing, otherwise,
            //divy out everything left over (which will be everything)
            foreach (DataGridViewRow dueRow in dataViewDueRO.Rows) {
                String charge = (String)dueRow.Cells[Description.Index].Value;
                decimal due = (Decimal)dueRow.Cells[Due.Index].Value;

                if (due > 0 || payment <= 0) {
                    continue;
                }

                int chargeID = ManageCheckbooks.findTransactionID(charge);

                payment += due; //due is negative, so this will subtract how much the user owes

                tblCashReceiptsApplyToBindingSource.AddNew();

                RentalEaseDataSet.tblCashReceiptsApplyToRow row = ((DataRowView)tblCashReceiptsApplyToBindingSource.Current).Row as RentalEaseDataSet.tblCashReceiptsApplyToRow;
                row.CashReceiptsID = this.ReceiptID;
                row.ApplyTo = chargeID;

                if (payment >= 0) {
                    //payment is enough to cover this
                    row.Paid = due * -1; //convert to positive
                } else {
                    //doesn't have enough money to conver this, can only cover partial, or none
                    row.Paid = (due - payment) * -1; //math:
                    //money remaining $50, current charge = $60
                    //payment = 50 + -60 = -10
                    //row["Paid"] = (-60 - -10) * -1
                    //row["Paid"] = (-60 + 10) * -1
                    //row["Paid"] = -50 * -1
                    //row["Paid"] = 50
                }

                if (payment <= 0) {
                    break; //don't conintue, no more money to distribute
                }
            }

            isVirginRow = true;
        }

И эта функция сохраняет его в базе данных:

    protected override void saveToDatabase() {
        tblCashReceiptsBindingSource.EndEdit();
        isVirginRow = false;

        RentalEaseDataSet.tblCashReceiptsRow[] rows = rentalEaseDataSet.tblCashReceipts.Select("ID < 0") as RentalEaseDataSet.tblCashReceiptsRow[];
        int newID = -1;
        if (rows.Count() > 0) {
            tblCashReceiptsTableAdapter.Update(rows[0]);
            newID = rows[0].ID;
        }

        tblCashReceiptsTableAdapter.Update(rentalEaseDataSet.tblCashReceipts);


        //update table
        /*foreach (RentalEaseDataSet.tblCashReceiptsApplyToRow row in rentalEaseDataSet.tblCashReceiptsApplyTo.Select("CashReceiptsID = -1")) {
            row.CashReceiptsID = newID;
        }*/

        //update binding source
        DataRowView[] applicationsOld = new DataRowView[tblCashReceiptsApplyToBindingSource.List.Count];
        RentalEaseDataSet.tblCashReceiptsApplyToRow[] applicationsNew = new RentalEaseDataSet.tblCashReceiptsApplyToRow[tblCashReceiptsApplyToBindingSource.List.Count];
        tblCashReceiptsApplyToBindingSource.List.CopyTo(applicationsOld, 0);
        for (int i = 0; i < applicationsOld.Count(); i++) {
            RentalEaseDataSet.tblCashReceiptsApplyToRow row = applicationsOld[i].Row as RentalEaseDataSet.tblCashReceiptsApplyToRow;

            if (row.CashReceiptsID < 0) {
                applicationsNew[i] = rentalEaseDataSet.tblCashReceiptsApplyTo.NewRow() as RentalEaseDataSet.tblCashReceiptsApplyToRow;
                applicationsNew[i]["ID"] = row.ID;
                applicationsNew[i]["CashReceiptsID"] = this.ReceiptID;
                applicationsNew[i][2] = row[2];
                applicationsNew[i][3] = row[3];
                applicationsNew[i][4] = row[4];
                //row.Delete();
            }
        }
        for (int i = 0; i < applicationsOld.Count(); i++) {
            try {
                if ((int)applicationsOld[i].Row["ID"] < 0) {
                    applicationsOld[i].Row.Delete();
                }
            } catch (RowNotInTableException) {
                break;
            }
        }
        this.tblCashReceiptsApplyToBindingSource.Filter = "CashReceiptsID = " + this.ReceiptID;

        foreach (DataRow newRow in applicationsNew) {
            if (newRow == null) {
                break;
            }
            tblCashReceiptsApplyToBindingSource.AddNew();
            ((DataRowView)tblCashReceiptsApplyToBindingSource.Current).Row[0] = newRow[0];
            ((DataRowView)tblCashReceiptsApplyToBindingSource.Current).Row[1] = newRow[1];
            ((DataRowView)tblCashReceiptsApplyToBindingSource.Current).Row[2] = newRow[2];
            ((DataRowView)tblCashReceiptsApplyToBindingSource.Current).Row[3] = newRow[3];
            ((DataRowView)tblCashReceiptsApplyToBindingSource.Current).Row[4] = newRow[4];
        }

        tblCashReceiptsApplyToBindingSource.EndEdit();

        checkForBadRows();

        tblCashReceiptsApplyToTableAdapter.Update(rentalEaseDataSet.tblCashReceiptsApplyTo);
        tblCashReceiptsApplyToTableAdapter.Fill(rentalEaseDataSet.tblCashReceiptsApplyTo);
    }

1 Ответ

1 голос
/ 18 февраля 2011

Возможно, вы захотите попробовать добавить строки в DataGridView. Поскольку вы привязываетесь к нему, DataGridView становится вашей «точкой доступа».

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

Если вам нужна дополнительная информация, я могу обновить.

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