4.7.4. Working with Stored Procedures

The methods we will use for adding, editing and deleting illustrate how to work with stored procedures in Entity Framework. As an example, this is the method for adding a new record:

  1. private void btnAddInvoiceLine_Click(object sender, EventArgs e) {
  2. var dbContext = AppVariables.getDbContext();
  3. // get current invoice
  4. var invoice = dbContext.INVOICES.Find(this.CurrentInvoice.Id);
  5. if (invoice.PAYED == 1) {
  6. MessageBox.Show("The change is not possible, the invoice has already been paid.", "Error");
  7. return;
  8. }
  9. // create invoice position
  10. var invoiceLine = dbContext.INVOICE_LINES.Create();
  11. invoiceLine.INVOICE_ID = invoice.INVOICE_ID;
  12. // create the position editor of the invoice
  13. using (InvoiceLineEditorForm editor = new InvoiceLineEditorForm()) {
  14. editor.Text = "Add invoice line";
  15. editor.InvoiceLine = invoiceLine;
  16. // Form Close Handler
  17. editor.FormClosing += delegate (object fSender, FormClosingEventArgs fe) {
  18. if (editor.DialogResult == DialogResult.OK) {
  19. try {
  20. // create SP parameters
  21. var invoiceIdParam = new FbParameter("INVOICE_ID",
  22. FbDbType.Integer);
  23. var productIdParam = new FbParameter("PRODUCT_ID",
  24. FbDbType.Integer);
  25. var quantityParam = new FbParameter("QUANTITY", FbDbType.Integer);
  26. // initial parameters values
  27. invoiceIdParam.Value = invoiceLine.INVOICE_ID;
  28. productIdParam.Value = invoiceLine.PRODUCT_ID;
  29. quantityParam.Value = invoiceLine.QUANTITY;
  30. // execute stored procedure
  31. dbContext.Database.ExecuteSqlCommand(
  32. "EXECUTE PROCEDURE SP_ADD_INVOICE_LINE("
  33. + "@INVOICE_ID, @PRODUCT_ID, @QUANTITY)",
  34. invoiceIdParam,
  35. productIdParam,
  36. quantityParam);
  37. // refresh grids
  38. // reload current invoice record
  39. CurrentInvoice.Load(invoice.INVOICE_ID);
  40. // reload all record in detail grid
  41. LoadInvoiceLineData(invoice.INVOICE_ID);
  42. // refresh all related data
  43. masterBinding.ResetCurrentItem();
  44. }
  45. catch (Exception ex) {
  46. // display error
  47. MessageBox.Show(ex.Message, "Error");
  48. // Do not close the form to correct the error
  49. fe.Cancel = true;
  50. }
  51. }
  52. };
  53. editor.ShowDialog(this);
  54. }
  55. }

With our example, an update of the master grid record will be needed because one of its fields (TotalSale) contains aggregated information derived from the detail lines of the document. This is how we do that:

  1. private void btnEditInvoiceLine_Click(object sender, EventArgs e) {
  2. var dbContext = AppVariables.getDbContext();
  3. // get current invoice
  4. var invoice = dbContext.INVOICES.Find(this.CurrentInvoice.Id);
  5. if (invoice.PAYED == 1) {
  6. MessageBox.Show("The change is not possible, the invoice has already been paid.",
  7. "Error");
  8. return;
  9. }
  10. // get current invoice position
  11. var invoiceLine = invoice.INVOICE_LINES
  12. .Where(p => p.INVOICE_LINE_ID == this.CurrentInvoiceLine.Id)
  13. .First();
  14. // create invoice position editor
  15. using (InvoiceLineEditorForm editor = new InvoiceLineEditorForm()) {
  16. editor.Text = "Edit invoice line";
  17. editor.InvoiceLine = invoiceLine;
  18. // form close handler
  19. editor.FormClosing += delegate (object fSender, FormClosingEventArgs fe) {
  20. if (editor.DialogResult == DialogResult.OK) {
  21. try {
  22. // create parameters
  23. var idParam = new FbParameter("INVOICE_LINE_ID", FbDbType.Integer);
  24. var quantityParam = new FbParameter("QUANTITY", FbDbType.Integer);
  25. // initial parameters values
  26. idParam.Value = invoiceLine.INVOICE_LINE_ID;
  27. quantityParam.Value = invoiceLine.QUANTITY;
  28. // execute stored procedure
  29. dbContext.Database.ExecuteSqlCommand(
  30. "EXECUTE PROCEDURE SP_EDIT_INVOICE_LINE("
  31. + "@INVOICE_LINE_ID, @QUANTITY)",
  32. idParam,
  33. quantityParam);
  34. // refresh grids
  35. // reload current invoice record
  36. CurrentInvoice.Load(invoice.INVOICE_ID);
  37. // reload all records in detail grid
  38. LoadInvoiceLineData(invoice.INVOICE_ID);
  39. // refresh all related controls
  40. masterBinding.ResetCurrentItem();
  41. }
  42. catch (Exception ex) {
  43. // display error
  44. MessageBox.Show(ex.Message, "Error");
  45. // Do not close the form to correct the error
  46. fe.Cancel = true;
  47. }
  48. }
  49. };
  50. editor.ShowDialog(this);
  51. }
  52. }

Deleting an Invoice Detail Line

The method for deleting a detail record is implemented as follows:

  1. private void btnDeleteInvoiceLine_Click(object sender, EventArgs e) {
  2. var result = MessageBox.Show(
  3. " Are you sure you want to delete the invoice item?",
  4. "Confirmation",
  5. MessageBoxButtons.YesNo,
  6. MessageBoxIcon.Question);
  7. if (result == DialogResult.Yes) {
  8. var dbContext = AppVariables.getDbContext();
  9. // get current invoice
  10. var invoice = dbContext.INVOICES.Find(this.CurrentInvoice.Id);
  11. try {
  12. if (invoice.PAYED == 1)
  13. throw new Exception("It is not possible to delete the entry, the invoice is paid.");
  14. // create parameters
  15. var idParam = new FbParameter("INVOICE_LINE_ID", FbDbType.Integer);
  16. // initialize parameters values
  17. idParam.Value = this.CurrentInvoiceLine.Id;
  18. // execute stored procedure
  19. dbContext.Database.ExecuteSqlCommand(
  20. "EXECUTE PROCEDURE SP_DELETE_INVOICE_LINE(@INVOICE_LINE_ID)",
  21. idParam);
  22. // update grids
  23. // reload current invoice
  24. CurrentInvoice.Load(invoice.INVOICE_ID);
  25. // reload all records in detail grids
  26. LoadInvoiceLineData(invoice.INVOICE_ID);
  27. // refresh related controls
  28. masterBinding.ResetCurrentItem();
  29. }
  30. catch (Exception ex) {
  31. // display error
  32. MessageBox.Show(ex.Message, "Error");
  33. }
  34. }
  35. }