//Adds new product to database private void btnSubmitProd_Click(object sender, EventArgs e) { if (Validator.IsPresent("Product Name", prodNameTextBox)) { Product newProduct = new Product { ProdName = prodNameTextBox.Text }; using (travelexpertsDataContext db = new travelexpertsDataContext()) { Product ExistingProduct = db.Products.SingleOrDefault(p => p.ProdName == newProduct.ProdName); if (ExistingProduct != null) { MessageBox.Show("Product Already Exists"); } else { db.Products.InsertOnSubmit(newProduct); db.SubmitChanges(); DialogResult = DialogResult.OK; MessageBox.Show("New product added"); } } } }
// Takes current selected Product_Supplier and adds it to the package [Ronnie] private void btnAdd_Click(object sender, EventArgs e) { // Get ProductSupplierID from combobox int prodSupID = Convert.ToInt32(productSupplierIdTextBox.Text); int packageID = currentPackage.PackageId; // if the current product and supplier combination does not exist for the package, add it to the database if (!TravelExpertsQueryManager.ExistPackagesProductsSupplier(packageID, prodSupID)) { // Create a PackagesProductSupplier with that ID, and the Package ID from the current package Packages_Products_Supplier newPackProdSup = new Packages_Products_Supplier { ProductSupplierId = prodSupID, PackageId = packageID }; // Add that PackagesProductsSupplier to the db using (travelexpertsDataContext dbContext = new travelexpertsDataContext()) { // insert through data context object from the main form dbContext.Packages_Products_Suppliers.InsertOnSubmit(newPackProdSup); dbContext.SubmitChanges(); // submit to the database } // Re-load the datagrid view refreshDataGrid(); } else { MessageBox.Show("The selected product and supplier portfolio has already been added to the package. Please try again.", "Input Error"); } }
//submits new supplier to database private void btnSubmit_Click(object sender, EventArgs e) { if (Validator.IsPresent("Supplier Name", supplierAddTextBoc)) { Supplier newSupplier = new Supplier { SupName = supplierAddTextBoc.Text }; using (travelexpertsDataContext db = new travelexpertsDataContext()) { Supplier existingSup = db.Suppliers.SingleOrDefault(s => s.SupName == newSupplier.SupName); if (existingSup != null) { MessageBox.Show("Supplier already exists");//doesnt allow existing suppliers to be added } else { db.Suppliers.InsertOnSubmit(newSupplier); db.SubmitChanges(); DialogResult = DialogResult.OK; MessageBox.Show("New Supplier added"); } } } }
// Checks to ensure valid fields and then updates the current package entry in the database. // Note: we insert a new Package with default properties when entering this form in add mode. // As such, the save button functions the same in either mode. See Load and Cancel code for differences. private void btnSave_Click(object sender, EventArgs e) { // VALIDATION [Ronnie] if (Validator.IsPresent("Name", pkgNameTextBox) && Validator.IsPresent("Description", pkgDescTextBox) && Validator.IsPresent("Base Price", pkgBasePriceTextBox) && Validator.IsValidEndDate(pkgStartDateDateTimePicker, pkgEndDateDateTimePicker, ref tmpEndDate) && Validator.IsDecimal("Base Price", pkgBasePriceTextBox) && (pkgAgencyCommissionTextBox.Text == "" || (Validator.IsDecimal("Agency Commission", pkgAgencyCommissionTextBox) && Validator.IsNonNegativeDecimal("Agency Commission", pkgAgencyCommissionTextBox) && Validator.IsLEBasePrice(pkgBasePriceTextBox, pkgAgencyCommissionTextBox) )) && Validator.IsNonNegativeDecimal("Base Price", pkgBasePriceTextBox) ) { try { using (travelexpertsDataContext db = new travelexpertsDataContext()) { // get the product with Code from the current text box Package packageFromDB = db.Packages.Single(p => p.PackageId == currentPackage.PackageId); //MessageBox.Show("Testing concurrency: update or delete current record from SSMS and click OK"); if (packageFromDB != null) { // make changes by copying values from text boxes packageFromDB.PkgName = pkgNameTextBox.Text; packageFromDB.PkgStartDate = tmpStartDate; packageFromDB.PkgEndDate = tmpEndDate; packageFromDB.PkgDesc = pkgDescTextBox.Text; packageFromDB.PkgBasePrice = Decimal.Parse(pkgBasePriceTextBox.Text, System.Globalization.NumberStyles.Currency); //AgencyCommission can be null, so we check for that first if (pkgAgencyCommissionTextBox.Text == "") { packageFromDB.PkgAgencyCommission = null; } // If not null, we have to parse it out of the formatted textbox else { packageFromDB.PkgAgencyCommission = Decimal.Parse(pkgAgencyCommissionTextBox.Text, System.Globalization.NumberStyles.Currency); } // submit changes db.SubmitChanges(); DialogResult = DialogResult.OK; this.Close(); } } } catch (Exception ex) { MessageBox.Show(ex.Message, ex.GetType().ToString()); } } }
//loads the current supplier from the supplier page private void frmSupplierModify_Load(object sender, EventArgs e) { using (travelexpertsDataContext db = new travelexpertsDataContext()) { supplierIdTextBox.Text = Convert.ToString(currentSupplier.SupplierId); supplierNameTextBox.Text = currentSupplier.SupName; } }
private void refreshDataGrid() { // Populate data grid showing products using (travelexpertsDataContext db = new travelexpertsDataContext()) { grdProdSup.DataSource = TravelExpertsQueryManager.FindProdInfoByPackage(db, currentPackage.PackageId); } }
//loads the current product from the product page private void frmProductsModify_Load(object sender, EventArgs e) { using (travelexpertsDataContext db = new travelexpertsDataContext()) { OldName = currentProduct.ProdName; productIdTextBox.Text = Convert.ToString(currentProduct.ProductId); prodNameTextBox.Text = currentProduct.ProdName; } }
private void DisplayProdSupId() { using (travelexpertsDataContext db = new travelexpertsDataContext()) { int prodId = Convert.ToInt32(prodNameComboBox.SelectedValue); int supId = Convert.ToInt32(supNameComboBox.SelectedValue); productSupplierIdTextBox.Text = TravelExpertsQueryManager.FindProdSuppID(db, prodId, supId).ToString(); } }
// Updates the display of the prodsuppID private void RefreshProdSupId() { using (travelexpertsDataContext db = new travelexpertsDataContext()) { int prodId = Convert.ToInt32(productIdComboBox.SelectedValue); // grabs id from product dropdown int supId = Convert.ToInt32(supplierIdComboBox.SelectedValue); // grabs id from supplier dropdown productSupplierIdTextBox.Text = TravelExpertsQueryManager.FindProdSuppID(db, prodId, supId).ToString(); // uses that data to grab the corresponding prodsup id } }
/// <summary> /// Validates whether or not a given product and supplier combination already exists in the database. [Eric] /// </summary> /// <param name="db">Database context</param> /// <param name="prodId">Int product ID to check</param> /// <param name="supId">Int supplier ID to check</param> /// <param name="prodSupId">Optional - An existing productsupplier entry to disregard (if modifying an exisiting one, in case it's left unchanged).</param> /// <returns></returns> public static Products_Supplier prodSupComboAlreadyExists(travelexpertsDataContext db, int prodId, int supId, int prodSupId = -1) { var matchingProps = db.Products_Suppliers // search the Products_Suppliers table for entries... .Where(ps => ps.ProductId == prodId) // ...matching the new product id... .Where(ps => ps.SupplierId == supId) // ... and matching the new supplier id... .Where(ps => ps.ProductSupplierId != prodSupId) //... but with a different prodsupplierID .FirstOrDefault(); // We can stop at the first, though there won't be more than one // If no match was found, we're good return(matchingProps); }
private void prodNameComboBox_SelectedIndexChanged(object sender, EventArgs e) { // get the list of suppliers applicable with the selected product ID using (travelexpertsDataContext db = new travelexpertsDataContext()) { supNameComboBox.DataSource = TravelExpertsQueryManager.GetSuppliersByProductID(db, Convert.ToInt32(prodNameComboBox.SelectedValue)); DisplayProdSupId(); } }
// Updates the data and display just for the grid of associated products, based on current selection of package datagrid private void RefreshProductGrid() { // Grab ID of the row currently selected in the Packages Datagrid. [Eric] selectedPackageId = Convert.ToInt32(grdPackages.CurrentRow.Cells[0].Value); // Set title for the products data using that current id lblSelectedProdsTitle.Text = $"Products for Selected Package (ID #{selectedPackageId})"; // Populate data in Product Info gridview using (travelexpertsDataContext db = new travelexpertsDataContext()) { // Use an in-depth query to grab the info needed for the product info data grid dataGridView1.DataSource = TravelExpertsQueryManager.FindProdInfoByPackage(db, selectedPackageId); } }
// Initial form setup private void frmProdSupplierAddEdit_Load(object sender, EventArgs e) { // On load, populate data for all data displays rootDB = new travelexpertsDataContext(); // create a new context //get product_supplier data for top datagrid products_SupplierBindingSource.DataSource = TravelExpertsQueryManager.GetProductsSuppliersExtended(rootDB); selectedProdID = Convert.ToInt32(grdProductSuppliers.Rows[0].Cells[0].Value); // set selectedProdID as ID of top row lblSelectedProdsTitle.Text = $"Modify details for selected product (ID #{selectedProdID})"; // Set display for that ID supplierIdComboBox.DataSource = rootDB.Suppliers; // get supplier data for suppliers details dropbox productIdComboBox.DataSource = rootDB.Products; // get product data for products details dropbox RefreshPackagesByProdSuppGrid(); // get package data for selected product_supplier row (in this case, top one) SetDataGridToFirstEntry(); // Selects the first row of the main datagrid }
private void frmProdSupplier_Load(object sender, EventArgs e) { // Populate data grid showing products using (travelexpertsDataContext db = new travelexpertsDataContext()) { refreshDataGrid(); // display the list of selection for products and suppliers prodNameComboBox.DataSource = db.Products; prodNameComboBox.DisplayMember = "ProdName"; prodNameComboBox.ValueMember = "ProductId"; supNameComboBox.DisplayMember = "SupName"; supNameComboBox.ValueMember = "SupplierId"; } lblDesc.Text = $"Add or remove associated products from this package (ID#{currentPackage.PackageId}: {currentPackage.PkgName})"; }
private void btnModify_Click(object sender, EventArgs e) { using (travelexpertsDataContext db = new travelexpertsDataContext()) { currentProduct = (from p in db.Products where p.ProductId == selectProductId select p).Single(); frmProductsModify frmprodmodify = new frmProductsModify(); frmprodmodify.currentProduct = currentProduct; DialogResult result = frmprodmodify.ShowDialog(); if (result == DialogResult.OK || result == DialogResult.Retry) // successful update or concurrency exception { RefreshView(); } } }
//If Modify Button was clicked on Form1 private void frmAddModify_Load(object sender, EventArgs e) { if (!isAdd) // Set up for Modify mode - use the Package passed from the last form to populate fields { // Update the title and description of the page lblTitle.Text = "Package Manager - Edit Package"; lblDesc.Text = $"Edit any details and modify product list for the current package (ID #{currentPackage.PackageId})."; using (travelexpertsDataContext db = new travelexpertsDataContext()) { // Grab current package ID used to create this modify page int packageId = currentPackage.PackageId; // Use an in-depth query to grab the info needed for the product info data grid dataGridView1.DataSource = TravelExpertsQueryManager.FindProdInfoByPackage(db, currentPackage.PackageId); } // Set up a snapshot of current associated package_product_suppliers entries ppsSnapshot = TravelExpertsQueryManager.GetPackagesProductsSuppliersByPackageID(currentPackage.PackageId); // handle nullable datetime if (currentPackage.PkgStartDate == null) { EmptyDateTimePicker(pkgStartDateDateTimePicker); } if (currentPackage.PkgEndDate == null) { EmptyDateTimePicker(pkgEndDateDateTimePicker); } // Display current package information in details view packageBindingSource.Add(currentPackage); } else // Set up for Add mode { // Update the title and description of the page lblTitle.Text = "Package Manager - Add A New Package"; lblDesc.Text = "Add details and products for a new package."; EmptyDateTimePicker(pkgStartDateDateTimePicker); EmptyDateTimePicker(pkgEndDateDateTimePicker); } }
//To add Products to a Package - calls form ProdSuppliers private void btnEditAddProducts_Click(object sender, EventArgs e) { frmProdSupplier prodsForm = new frmProdSupplier(); prodsForm.currentPackage = currentPackage; DialogResult result = prodsForm.ShowDialog(); // display second form modal if (result == DialogResult.OK) // new row got inserted { // Toggle a switch noting that products were updated - checked in the event of cancel didAddProducts = true; // Show the updated list of products associated with this package using (travelexpertsDataContext db = new travelexpertsDataContext()) { dataGridView1.DataSource = TravelExpertsQueryManager.FindProdInfoByPackage(db, currentPackage.PackageId); } } }
//Allows modifications to Packages private void btnModify_Click(object sender, EventArgs e) { //Package currentPackage; using (travelexpertsDataContext dbContext = new travelexpertsDataContext()) { currentPackage = (from p in dbContext.Packages // LINQ query that returns one record where p.PackageId == selectedPackageId // use ID of selected row in Packages select p).Single(); // method Single runs the LINQ query, only when receiving one value frmAddModify secondForm = new frmAddModify(); secondForm.isAdd = false; // Modify mode secondForm.currentPackage = currentPackage; DialogResult result = secondForm.ShowDialog(); // display second form modal if (result == DialogResult.OK || result == DialogResult.Retry) // successful update or concurrency exception { RefreshView(); } } }
//Delete from GridView so it won't add to database [Ronnie] private void btnDelete_Click(object sender, EventArgs e) { // Grab data from selected cell on gridview int rowNum = grdProdSup.CurrentCell.RowIndex; // index of the current row int prodSuppID = Convert.ToInt32(grdProdSup[0, rowNum].Value); // Column for ProductSupplierID using (travelexpertsDataContext dbContext = new travelexpertsDataContext()) { // Packages_Products_Supplier packProdSupForRemoval = (from match in dbContext.Packages_Products_Suppliers where (match.ProductSupplierId == prodSuppID && match.PackageId == currentPackage.PackageId) select match).Single(); dbContext.Packages_Products_Suppliers.DeleteOnSubmit(packProdSupForRemoval); dbContext.SubmitChanges(); // submit to the database } refreshDataGrid(); }
// Checking off the top filter button will toggle filtering all products in the product_supplier datagrid (either all of them, or just those with packages) private void checkboxFilterProducts_CheckedChanged(object sender, EventArgs e) { // Update the persisting db image (used as a data source) rootDB = new travelexpertsDataContext(); // If the user checks off the option to filter if (checkboxFilterProducts.Checked == true) { // Query PPS to find all ProductSuppliers associated to packages List <int> prodSupIDsWithPackages = rootDB.Packages_Products_Suppliers.Select(pps => pps.ProductSupplierId) // just need ids .ToList(); // Filter the datagrid to only show those entries products_SupplierBindingSource.DataSource = TravelExpertsQueryManager.GetProductsSuppliersExtended(rootDB, prodSupIDsWithPackages); } else { products_SupplierBindingSource.DataSource = TravelExpertsQueryManager.GetProductsSuppliersExtended(rootDB); } }
//submits modified supplier to database private void btnModify_Click(object sender, EventArgs e) { if (Validator.IsPresent("Supplier Name", supplierNameTextBox)) { using (travelexpertsDataContext db = new travelexpertsDataContext()) { Supplier supplierfrmDB = db.Suppliers.Single(p => p.SupplierId.ToString() == supplierIdTextBox.Text); List <Supplier> ExistingSupplier = db.Suppliers.Where(q => q.SupName == supplierNameTextBox.Text).ToList(); if (ExistingSupplier.Count > 0 && ExistingSupplier[0].SupName != currentSupplier.SupName) { MessageBox.Show("Cannor modify Supplier because supplier name already exists"); } else if (supplierNameTextBox.Text != supplierfrmDB.SupName) { supplierfrmDB.SupName = supplierNameTextBox.Text; db.SubmitChanges(); DialogResult = DialogResult.OK; MessageBox.Show("Supplier Modified"); } } } }
// Whenever the user selects a product from the dropdown, update the suppliers dropdown with appropriate data [Eric] private void productIdComboBox_SelectedIndexChanged(object sender, EventArgs e) { using (travelexpertsDataContext db = new travelexpertsDataContext()) { // If the user has selected the option to filter suppliers if (checkBoxFilterSuppliers.Checked == true) { // Get the list of suppliers applicable with the selected product ID supplierIdComboBox.DataSource = TravelExpertsQueryManager.GetSuppliersByProductID(db, Convert.ToInt32(productIdComboBox.SelectedValue)); // Make top option of suppliers dropdown selected supplierIdComboBox.SelectedIndex = 0; } else { supplierIdComboBox.DataSource = db.Suppliers; // get supplier data for suppliers details dropbox // Make top option of suppliers dropdown selected supplierIdComboBox.SelectedIndex = 0; } } }
//submits modified product to database private void btnModify_Click(object sender, EventArgs e) { if (Validator.IsPresent("Product Name", prodNameTextBox)) { using (travelexpertsDataContext db = new travelexpertsDataContext()) { Product productFromDB = db.Products.Single(p => p.ProductId.ToString() == productIdTextBox.Text); List <Product> ExistingProdut = db.Products.Where(q => q.ProdName == prodNameTextBox.Text).ToList(); if (ExistingProdut.Count > 0 && ExistingProdut[0].ProdName != currentProduct.ProdName) { MessageBox.Show("Cannot modify product because product already exists"); } else if (prodNameTextBox.Text != productFromDB.ProdName) { productFromDB.ProdName = prodNameTextBox.Text; db.SubmitChanges(); DialogResult = DialogResult.OK; MessageBox.Show("Proudct modified"); } } } }
//Adds new Packages to Database private void btnAdd_Click(object sender, EventArgs e) { frmAddModify secondForm = new frmAddModify(); secondForm.isAdd = true; // Because we give the user the option to add products to the new package before saving it, // we need to do a preliminary insert into the database in order to get a valid PackageID // for the PackageProductsSuppliers table. // We don't use the current highest PackageID + 1, in order to avoid concurrency issues. // These alterations done by [Eric] Package newPackage = new Package { PkgName = "DEFAULT", PkgStartDate = DateTime.Now, PkgEndDate = DateTime.Now, PkgDesc = "DEFAULT", PkgBasePrice = 0, PkgAgencyCommission = 0 }; // submit changes to database using (travelexpertsDataContext db = new travelexpertsDataContext()) { db.Packages.InsertOnSubmit(newPackage); // insert the new package through data context object db.SubmitChanges(); //submit to database } secondForm.currentPackage = newPackage; // Now that the new package has been added to the database, the Object has an Id (magic!) DialogResult result = secondForm.ShowDialog(); // display second form modal if (result == DialogResult.OK) // new row got inserted { secondForm.Close(); RefreshView(); } }
// Modifies the ProductSupplier associated with the selected row of the datagrid using the user inputs [Eric] private void btnModifyProdSupp_Click(object sender, EventArgs e) { // Get user inputs int newProdId = Convert.ToInt32(productIdComboBox.SelectedValue); int newSupID = Convert.ToInt32(supplierIdComboBox.SelectedValue); // The user may not have selected a value for the supplierIDComboBox yet, if so, they want the visible (top) one if (newSupID == 0) { supplierIdComboBox.SelectedIndex = 0; newSupID = Convert.ToInt32(supplierIdComboBox.SelectedValue); } // grab data from dropdown selectedvalues & hidden id field (productSupplierIdTextBox) using (travelexpertsDataContext db = new travelexpertsDataContext()) { if (addMode == false) // if modifying { // Get current product supplier ID int prodSupID = Convert.ToInt32(productSupplierIdTextBox.Text); // Grab the current entry from the database Products_Supplier prodSup = db.Products_Suppliers .Single(ps => ps.ProductSupplierId == prodSupID); // Validate by ensuring this unique combination isn't in the database Products_Supplier matchingProps = Validator.prodSupComboAlreadyExists(db, newProdId, newSupID, prodSupID); if (matchingProps == null) { // Update with inputted values prodSup.ProductId = newProdId; prodSup.SupplierId = newSupID; db.SubmitChanges(); } else // there is a match for the product/supplier combo { //Give the user the option to change to this combination anyway (this will move all associated packages to the matching Product_Supplier) DialogResult result = MessageBox.Show($"That product/supplier combination already exists (ID #{matchingProps.ProductSupplierId} - {matchingProps.Product.ProdName} - {matchingProps.Supplier.SupName}). Would you like to change any associated packages to have the selected product?", "Existing Product/Supplier", MessageBoxButtons.YesNo); if (result == DialogResult.Yes) { // Get all Package_Product_Suppliers entries that refer to the current ProdSup ID (these will need to be modified) List <Packages_Products_Supplier> ppsWithCurrentProdSupID = db.Packages_Products_Suppliers.Where(pps => pps.ProductSupplierId == prodSupID).ToList(); // Go through each, updating the ProdSupID to the existing combination foreach (Packages_Products_Supplier pps in ppsWithCurrentProdSupID) { // We can't directly update ProdSupID in an existing entry as it is part of the entry's Primary key. //Instead, we have to delete it and create a new one. int currentPackageId = pps.PackageId; // to keep track of the package ID db.Packages_Products_Suppliers.DeleteOnSubmit(pps); db.SubmitChanges(); // have to submit changes here otherwise we can't create a new one try { using (travelexpertsDataContext db2 = new travelexpertsDataContext()) { // Now, create a new PPS using the PPS and the new ProdSupID Packages_Products_Supplier newPps = new Packages_Products_Supplier { PackageId = currentPackageId, // the same package id ProductSupplierId = matchingProps.ProductSupplierId // the prod_sup id that matches what the user wants to change it to }; db2.Packages_Products_Suppliers.InsertOnSubmit(newPps); db2.SubmitChanges(); } } catch (Exception ex) { MessageBox.Show(ex.Message, ex.GetType().ToString()); } } MessageBox.Show($"Any associated packages successfully transffered to ID# {matchingProps.ProductSupplierId} - {matchingProps.Product.ProdName} - {matchingProps.Supplier.SupName})"); } } // Reload data checkboxFilterProducts_CheckedChanged(sender, e);//this updates the main datagrid based on whether the filter is on RefreshPackagesByProdSuppGrid(); RefreshProdSupId(); } // end modify else // if in add mode { // Validate to ensure the combo is new Products_Supplier match = Validator.prodSupComboAlreadyExists(db, newProdId, newSupID); if (match == null) //if new { // create a new Product_Supplier with the data Products_Supplier newProdSup = new Products_Supplier { ProductId = newProdId, SupplierId = newSupID }; // insert into db and save db.Products_Suppliers.InsertOnSubmit(newProdSup); db.SubmitChanges(); // Re-enable Add new button btnAddProdSupp.Enabled = true; // Reload main data checkboxFilterProducts_CheckedChanged(sender, e); //updates main datagrid based on status of filter checkbox // Go to the new entry in the gridview checkboxFilterProducts.Checked = false; // uncheck filter so new product can be seen int lastIndex = grdProductSuppliers.Rows.Count - 1; // get last row of the grid grdProductSuppliers.Rows[lastIndex].Selected = true; // select it grdProductSuppliers.FirstDisplayedScrollingRowIndex = lastIndex; // go down to it grdProductSuppliers_CellClick(sender, new DataGridViewCellEventArgs(1, lastIndex)); // Reload related data RefreshPackagesByProdSuppGrid(); productIdComboBox_SelectedIndexChanged(sender, e); RefreshProdSupId(); } else // if the combo already exists { // Alert the user MessageBox.Show($"That product/supplier combination already exists (ID #{match.ProductSupplierId})."); } } } }
// Go back to last page without saving changes. This may involve some cleaning up, depending on the mode and if products were added [Eric] private void btnCancel_Click(object sender, EventArgs e) { using (travelexpertsDataContext dbContext = new travelexpertsDataContext()) { // First, we have to check to see if any products were added to the package before cancelling if (didAddProducts) // this will be true if so - no need to spend time querying the db { // Get the current PPS entries in the database corresponsind to this package List <Packages_Products_Supplier> ppsCurrent = TravelExpertsQueryManager.GetPackagesProductsSuppliersByPackageID(currentPackage.PackageId); // Next, we have to get the PPS entries to re-add (if they were deleted) and/or remove (if new ones were added) // This is not a super efficient process, but packages shouldn't have enough products for it to make much difference // First, get the ones to re-add List <Packages_Products_Supplier> ppsToAdd = ppsSnapshot // Creating a list of Package_Product_Suppliers where... .Where(ppsSnap => !ppsCurrent // ...for each snapshot entry, it is NOT the case that... .Any(ppsCurr => ppsCurr.ProductSupplierId == ppsSnap.ProductSupplierId)) // ...any current entry has that snapshot entry's ProductSupplierID .ToList(); // Next, the ones to remove List <Packages_Products_Supplier> ppsToDelete = ppsCurrent // Creating a list of Package_Product_Suppliers where... .Where(ppsCurr => !ppsSnapshot // ...for each current entry, it is NOT the case that... .Any(ppsSnap => ppsCurr.ProductSupplierId == ppsSnap.ProductSupplierId)) // ...any snapshot entry has that current entry's ProductSupplierID .ToList(); // Add the needed entries back foreach (Packages_Products_Supplier ppsA in ppsToAdd) { // LINQ to SQL doesn't let you re-add old entity objects, so we need to create copies to add back in place Packages_Products_Supplier clone = new Packages_Products_Supplier { PackageId = ppsA.PackageId, ProductSupplierId = ppsA.ProductSupplierId }; dbContext.Packages_Products_Suppliers.InsertOnSubmit(clone); } // Delete the entries to undo foreach (Packages_Products_Supplier ppsD in ppsToDelete) { // Deleting only works on entities from the current context, so need to grab them // I'm sure this could be done in the ones-to-remove LINQ query above, but I couldn't manage it Packages_Products_Supplier deleteTarget = dbContext.Packages_Products_Suppliers // Search in the table... .Single(pps => // ...for the one entry, with... pps.ProductSupplierId == ppsD.ProductSupplierId && //...the matching ProductSupplierID... pps.PackageId == ppsD.PackageId); //... and the matching PackageID dbContext.Packages_Products_Suppliers.DeleteOnSubmit(deleteTarget); } // Save changes. Phew! dbContext.SubmitChanges(); } // One more step if in Add mode. // A package was inserted into the database initially (to get the add products half to work). // So, if cancelling, we want to delete it this created package. if (isAdd) { // Delete package Package packToDelete = dbContext.Packages .Single(p => p.PackageId == currentPackage.PackageId); dbContext.Packages.DeleteOnSubmit(packToDelete); dbContext.SubmitChanges(); // submit to the database } } // Exit the form DialogResult = DialogResult.Cancel; this.Close(); }