Handling Unique ID error
-
Thursday, April 26, 2012 8:35 AM
Hi everyone
I have the following issue. I have an ID field that needs to be put in manually and that needs to be unique. It is the primary key in my database so the unique error will fire if I try to insert the same ID. The problem is in the handling of the error. If I do this:
catch (Exception ex) { transaction.Rollback(); MessageBox.Show("Doslo je do greske " + ex.Message); } }
It will give me a message box which shows the error but this code
public void SaveDobavljac(Dobavljac dobavljac) { if (dobavljac.IsNew== true) { if (!CurrentDobavljac.Contains(dobavljac)) CurrentDobavljac.Add(dobavljac); _dobavljacRepository.Save(dobavljac); StatusText = string.Format("Dobavljac '{0}' je spašen.", dobavljac.LookupDobavljac); } else { _dobavljacRepository.Update(dobavljac); } }still all goes through, so I still see the dobavljac in my grid.
On the other hand if I do this
catch (Exception ex) { transaction.Rollback(); throw new Exception("Failed to fill adapter. SQL is: '" + oleComd.CommandText + "' and error is: " + ex.Message); ; } }It will exit the application and show the error, which is not something I want to happen.
Ideally the solution would be for the textbox to go red and in the tooltip to show the error which is kinda how it works with the validation I have in place
but idealism is perhaps too ambitious so I would settle for the message box but the grid not showing the non existing (in the database) row.
Hopefully one of you guys can help me achieve this.
All Replies
-
Thursday, April 26, 2012 8:46 AM
hi,
put the
try catch
in the
SaveDobavljac
sub, and switch the save code with the add code:
public void SaveDobavljac(Dobavljac dobavljac) { if (dobavljac.IsNew== true) { if (!CurrentDobavljac.Contains(dobavljac)) { try { _dobavljacRepository.Save(dobavljac); CurrentDobavljac.Add(dobavljac); } catch { ... } } } }
If the exception occurs, it will not go trough with the add
Regards, Nico
-
Thursday, April 26, 2012 11:10 AM
Hi Nico, I tried your suggestion but unfortunately I still see the Dobavljac in the grid
public void SaveDobavljac(Dobavljac dobavljac) { if (dobavljac.IsNew== true) { if (!CurrentDobavljac.Contains(dobavljac)) try { CurrentDobavljac.Add(dobavljac); _dobavljacRepository.Save(dobavljac); StatusText = string.Format("Dobavljac '{0}' je spašen.", dobavljac.LookupDobavljac); } catch { MessageBox.Show("Doslo je do greske "); StatusText = string.Format("Dobavljac '{0}' nije spasen.", dobavljac.LookupDobavljac); } } else { _dobavljacRepository.Update(dobavljac); } }This is the code I tried with. When I debug it just jumps through the if (!CurrentDobavljac.Contains(dobavljac)) like it doesn't contain that dobavljac which I don't get since when I check the collection it has the id number that I am repeating. It's not GUID though, I use a regular INT since I need the user to insert it manually.
Thanks for your help.
-
Thursday, April 26, 2012 12:18 PMif you look at my code, it does the save first, then the add.
Regards, Nico
-
Friday, April 27, 2012 7:34 AM
Yeah I tried that as well but that still gives me the same issue.public void SaveDobavljac(Dobavljac dobavljac) { if (dobavljac.IsNew== true) { if (!CurrentDobavljac.Contains(dobavljac)) try { _dobavljacRepository.Save(dobavljac); CurrentDobavljac.Add(dobavljac); StatusText = string.Format("Dobavljac '{0}' je spašen.", dobavljac.LookupDobavljac); } catch { MessageBox.Show("Doslo je do greske "); StatusText = string.Format("Dobavljac '{0}' nije spasen.", dobavljac.LookupDobavljac); } } else { _dobavljacRepository.Update(dobavljac); } }I run the code and it gives me the error for the Unique Primary key but then It shows me theStatusText = string.Format("Dobavljac '{0}' je spašen.", dobavljac.LookupDobavljac);Which I don't understand. -
Tuesday, May 01, 2012 9:51 AMModerator
Hi,
I think the problem can be caused by this line of codes: if (!CurrentDobavljac.Contains(dobavljac))
What's the data type of CurrentDobavljac? How can it verify there is no duplicate primary keys of dbavljac objects inside? If it is just a generic List of dobavljac object, it will use the default method of .NET -- using object reference to check whether two objects are equal instead of their primary key value.
Good day!
Thanks
Michael Sun [MSFT]
MSDN Community Support | Feedback to us
-
Thursday, May 03, 2012 6:54 AM
Current Dobavljac is an Observable Collection
private ObservableCollection<Dobavljac> _currentDobavljac; _currentDobavljac = new ObservableCollection<Dobavljac>(dobavljacRepository.FindAll()); public ObservableCollection<Dobavljac> CurrentDobavljac { get { return _currentDobavljac; } set { _currentDobavljac = value; OnPropertyChanged("CurrentDobavljac"); } }
-
Thursday, May 03, 2012 1:15 PMModerator
Hi,
If you want to compare the objects in the ObserableCollection, I believe we need to create a comparer especially for the Dobavljac object. You can refer to the PersonComparer in this thread, http://forums.silverlight.net/t/50468.aspx
Good day!
Michael Sun [MSFT]
MSDN Community Support | Feedback to us
- Marked As Answer by dino2dy Thursday, May 10, 2012 7:46 AM
-
Thursday, May 03, 2012 1:27 PMThank you Michael I will give that a look.
-
Wednesday, May 09, 2012 10:38 AM
Ok so I tried the comparer. I created a class that compares my Primary keys which are Id's
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Inventar.Model; using Inventar.Presenters; using Inventar.Views; namespace Inventar.Presenters { class IdComparer : IEqualityComparer<Dobavljac> { // Products are equal if their Id's are equal. public bool Equals(Dobavljac x, Dobavljac y) { //Check whether the compared objects reference the same data. if (Object.ReferenceEquals(x, y)) return true; //Check whether any of the compared objects is null. if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null)) return false; //Check whether the products' properties are equal. return x.Dob_Id == y.Dob_Id; } // If Equals() returns true for a pair of objects // then GetHashCode() must return the same value for these objects. public int GetHashCode(Dobavljac dobavljac) { //Check whether the object is null if (Object.ReferenceEquals(dobavljac, null)) return 0; //Get hash code for the Code field. int hashProductCode = dobavljac.Dob_Id.GetHashCode(); //Calculate the hash code for the product. return hashProductCode; } } }Ok so that should compare the Dob.Id fields of the class Dobavljac, which are the primary keys.
So then in my insert code I do this:
public void SaveDobavljac(Dobavljac dobavljac) { if (dobavljac.IsNew== true) { //if (!CurrentDobavljac.Contains(dobavljac)) if (dobavljac.Dob_Id.Equals(false)) try { _dobavljacRepository.Save(dobavljac); CurrentDobavljac.Add(dobavljac); StatusText = string.Format("Dobavljac '{0}' je spašen.", dobavljac.LookupDobavljac); }This always skips everything.
If I try this
public void SaveDobavljac(Dobavljac dobavljac) { bool jednako=dobavljac.Dob_Id.Equals(new IdComparer()); if (dobavljac.IsNew== true) { //if (!CurrentDobavljac.Contains(dobavljac)) //if (dobavljac.Dob_Id.Equals(false)) if (jednako == false) try { _dobavljacRepository.Save(dobavljac); CurrentDobavljac.Add(dobavljac); StatusText = string.Format("Dobavljac '{0}' je spašen.", dobavljac.LookupDobavljac); }This always goes through the code, no matter if the primary key is a duplicate, so jednako is always false.
I also tried changing the IdComparer like this
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Inventar.Model; using Inventar.Presenters; using Inventar.Views; namespace Inventar.Presenters { class IdComparer : IEqualityComparer<Dobavljac> { public bool Equals(Dobavljac x, Dobavljac y) { if (x.Dob_Id == y.Dob_Id) { return true; } else { return false; } } public int GetHashCode(Dobavljac dobavljac) { //Check whether the object is null if (Object.ReferenceEquals(dobavljac, null)) return 0; //Get hash code for the Code field. int hashProductCode = dobavljac.Dob_Id.GetHashCode(); //Calculate the hash code for the product. return hashProductCode; } } }
No luck. I'm just no sure what I'm doing wrong.Please help.
- Edited by dino2dy Wednesday, May 09, 2012 11:07 AM
-
Wednesday, May 09, 2012 1:33 PMModerator
Hi,
I created such a demo for your references:
public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { ObservableCollection<MyObject> colleciton = new ObservableCollection<MyObject>(); MyObject o1 = new MyObject() { ID = 1, Name = "Michael" }; MyObject o2 = new MyObject() { ID = 1, Name = "Michael" }; colleciton.Add(o1); if (colleciton.Contains(o2, new IdComparer())) { MessageBox.Show("Duplicate"); } } } public class MyObject { public int ID { get; set; } public string Name { get; set; } } public class IdComparer : IEqualityComparer<MyObject> { public bool Equals(MyObject x, MyObject y) { if (x.ID == y.ID) { return true; } else { return false; } } public int GetHashCode(MyObject x) { if (x == null) return 0; return x.ID.GetHashCode(); } }
Or we can override the Equals and GetHashCode method of the Dobavljac object. Here are some sample codes:
public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { ObservableCollection<MyObject> colleciton = new ObservableCollection<MyObject>(); MyObject o1 = new MyObject() { ID = 1, Name = "Michael" }; MyObject o2 = new MyObject() { ID = 1, Name = "Michael" }; colleciton.Add(o1); if (colleciton.Contains(o2) { MessageBox.Show("Duplicate"); } } } public class MyObject { public int ID { get; set; } public string Name { get; set; } public override bool Equals(object obj) { MyObject o = obj as MyObject; return ID.Equals(o.ID); } public override int GetHashCode() { return ID.GetHashCode(); } }Good day!
Thanks
Michael Sun [MSFT]
MSDN Community Support | Feedback to us
- Marked As Answer by dino2dy Thursday, May 10, 2012 7:20 AM
-
Thursday, May 10, 2012 7:26 AM
Thank you so much Michael it works like a charm.
if (!CurrentDobavljac.Contains(dobavljac, new IdComparer))
I didn't know where to initialize the IdComparer, but your demo showed me.
You have been extremely helpful in this matter and I want to thank you once again for taking the time and having the patience to guide a newbie through this problem.
-
Thursday, May 10, 2012 7:54 AM
If I could bother you for one more thing and I can make a new thread but I figured since it's kinda related to ask you here.
Is there a way for me to avoid the message box that pops up and instead have the text box just go red and in the tooltip show the error. I had this other validation done this way.
I have created a Validators class that inherits from ValidationRule. And it fires a false Validation Result when the user tries to write in a non number or a 0.
namespace Inventar.Presenters { public class Validators:ValidationRule { public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo) { int IntValue=0; try { IntValue=Convert.ToInt16(value); } catch (Exception) { return new ValidationResult(false, "Molimo upišite broj"); } if (IntValue < 0) return new ValidationResult(false, "Molimo upišite broj veći od 0"); //if (!CurrentDobavljac.Contains(dobavljac, new IdComparer()))) return new ValidationResult (false, "Taj Dobavljac vec postoji"); return new ValidationResult(true, null); } } }Then in the back code for the View I have this Validation Error Event
private void TextBox_Error(object sender, ValidationErrorEventArgs e) { if (e.Action == ValidationErrorEventAction.Added) { ((Control)sender).ToolTip = e.Error.ErrorContent.ToString(); } else { ((Control)sender).ToolTip = ""; } }Which tells the text box what to do. And then in the wpf I just add this textbox_error event to the textbox of my choosing.
So is there a way to somehow implement this error handling for the Comparer as well?
If this is not possible, your solution works just fine, this is more a bells and whistles kinda thing.
-
Friday, May 11, 2012 1:40 AMModerator
Hi,
You're very welcome! :)
For the follow-up question about the validation in WPF, I would recommend you post a new thread in WPF forum here, http://social.msdn.microsoft.com/forums/en-US/wpf/threads/ Honestly, I am not a WPF expert. But I believe you will get very good support from the experts in WPF forum.
Have a nice weekend!
Thanks
Michael Sun [MSFT]
MSDN Community Support | Feedback to us
-
Friday, May 11, 2012 6:45 AMOk thank you once again Michael, and you have a great weekend as well!!!

