Το combo σου ΔΕΝ περιέχει strings. Έχει γίνει data binding σε ένα datatable οπότε και τα items που περιέχει ΔΕΝ είναι strings αλλά DataRowView. Δεν μπορείς να συγκρίνεις ένα DataRow με ένα string οπότε δεν μπορείς να χρησιμοποιήσεις έτσι απλά την SelectedItem.
Για να επιλέξεις κάτι σε αυτή την περίπτωση πρέπει να θέσεις την αντίστοιχη τιμή στο SelectedValue, όπως παρακάτω:
var table = new DataTable();
table.Columns.Add("ID", typeof (int));
table.Columns.Add("Name", typeof(string));
table.Rows.Add(1, "Eeeny");
table.Rows.Add(2, "Meeny");
table.Rows.Add(3, "Miny");
table.Rows.Add(4, "Moo");
this.comboBox1.DropDownStyle=ComboBoxStyle.DropDownList;
this.comboBox1.DisplayMember = "Name";
this.comboBox1.ValueMember = "Name";
this.comboBox1.DataSource = table;
this.comboBox1.SelectedValue = "Miny";
Γενικά πάντως σαν ValueMember χρησιμοποιείται το κλειδί μίας εγγραφής (π.χ. το ID) καθώς αυτό είναι που χρησιμοποιείται συνήθως στη βάση, όχι το λεκτικό.
Επιπλέον, ο κώδικας που έχεις γράψει για να εκτελέσεις το query είναι επικίνδυνος και αργός. Μπορεί άνετα κάποιος κακόβουλος χρήστης να δώσει κάποια "περίεργη" τιμή και να προκαλέσει SQL Injection. Για φαντάσου τί θα συμβεί αν δώσει '; DROP TABLE [20_Users]; -- .
Άλλο πρόβλημα του κώδικα είναι ότι μετατρέπει όλες τις τιμές σε ASCII, ακόμα και τις ημερομηνίες και τα νούμερα, πριν τα στείλει στο server με αποτέλεσμα διάφορα παρατράγουδα, αν π.χ. το 3.5 μεταφραστεί σε 3,5 ή η 31/12 φύγει ως 12/31. Και μην πούμε για τα προβλήματα όταν τα ελληνικά μετατραπούν σε ASCII.
Αντί για string concatenation θα πρέπει να χρησιμοποιήσεις
είτε parameterized queries είτε stored procedures (στα οποία θα περάσεις τις παραμέτρους ως ΠΑΡΑΜΕΤΡΟΥΣ, όχι με string concatenation). Το αποτέλεσμα είναι πιο ασφαλές, καθώς οι παράμετροι μεταφέρονται ξεχωριστά από το κείμενο και χωρίς μετατροπή σε string, ενώ είναι και πολύ γρηγορότερο καθώς ο SQL Server κάνει cache το execution plan κάθε query και μπορεί να κάνει parse πολύ γρηγορότερα τα parameterized queries που έχει ξαναδεί.
Για παράδειγμα, μπορείς να περάσεις το όνομα με τον παρακάτω τρόπο:
using (var connection = new SqlConnection(""))
{
// Create the command and set its properties.
var command = new SqlCommand("SELECT FullName FROM [20_Users] WHERE FName + ' ' + LName = '@fullName'",connection);
command.CommandType =CommandType.Text;
var parameter = new SqlParameter
{
ParameterName = "@fullName",
SqlDbType = SqlDbType.NVarChar,
Direction = ParameterDirection.Input,
Value = "some name"
};
// Add the parameter to the Parameters collection.
command.Parameters.Add(parameter);
// Open the connection and execute the reader.
connection.Open();
var attendant=(string)command.ExecuteScalar();
}
Τέλος, το WHERE είναι προβληματικό καθώς το contatenation σημαίνει ότι δεν μπορεί να χρησιμοποιηθεί κανένα index και ο server θα πρέπει να διαβάσει ολόκληρο τον πίνακα για να βρει το αποτέλεσμα. Θα ήταν καλύτερα να δημιουργήσεις είτε ένα calculated field με την τιμή του FullName το οποίο θα βάλεις σε ένα index ή να αλλάξεις το WHERE και να περνάς ξεχωριστά το First και το Last Name, δηλαδή να γίνει το εξής:
WHERE FName=@firstName AND LName=@lastName
Σε αυτή την περίπτωση θα πρέπει να δημιουργήσεις ένα άλλο index το οποίο θα περιλαμβάνει τα δύο πεδία.
Παναγιώτης Καναβός, Freelancer
Twitter: http://www.twitter.com/pkanavos