Hopefully i don't sound confusing but i am not sure if what i am trying to get at is possible.
I have a select statement to get name, id, guid. I am setting the display to name and the value to Id for each combobox. Is there a way that i could also assign the guid to the combo box so that i could use it in my winforms app?
here is what i have for select statement:
private void secondChild_drp_SelectedIndexChanged(object sender, EventArgs e)
{
string secondChildId = secondChild_drp.SelectedValue.ToString();
using (SqlConnection con = new SqlConnection(conString))
{
con.Open();
using (SqlDataAdapter sda = new SqlDataAdapter("SELECT ... WHERE em.ChildID = (" + secondChildId + ")", conString))
{
DataTable dt = new DataTable();
sda.Fill(dt);
thirdChild_drp.ValueMember = "ID";
thirdChild_drp.DisplayMember = "DisplayName";
thirdChild_drp.DataSource = dt;
}
}
cmd.CommandText="StoreProcName";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#ChildID", secondChildId);
cmd.Connection = con2;
con2.Open();
reader = cmd.ExecuteReader();
var guid = reader.ToString();
reader.Close();
con2.Close();
}
right now when i run this it tells me reader = cmd.ExecuteReader(); has Procedure or function StoreProcName has too many arguments specified.
i just want to get the guid associated with the id i passed in.
You can get the guid from your datatable as follows where yourselectedid is the combobox selecteditem id.
var results = from row in dt.AsEnumerable()
where row.Field<int>("ID") == yourselectedid
select row;
now from results you can get all the desired columns you want
Basically the same answer as I already posted here:
You could define a simple object which you are filling from your data base query:
public class Item
{
public int ID { get; set; }
public string DisplayName { get; set; }
public Guid Guid{ get; set; }
}
Your implementation could look something like this (some mockup data):
listBox1.DataSource = items;
listBox1.DisplayMember = "DisplayName";
listBox1.ValueMember = "ID";
Then based on the value you selected, you can query through your items and get the item:
var key = (int)listBox1.SelectedValue;
foreach (var existingItem in items)
{
if (existingItem.Key == key)
{
//woohoo got it!
Debug.Print(existingItem.Guid.ToString())
}
}
you can put both of the value in the value member, separated by whichever character for separator like : "12;0000-000-0000" then separate again the Value Menber with a String.Split.
Related
I have brought the data as below into the combobox. In my "BRANDS" table, the first column is brand_id and the second column is brand_name. I'm getting the names in the combobox, but I need to get the id's when saving it to the database. How can I do it ?
void markaekle() {
SqlCommand komut = new SqlCommand("Select * from MARKALAR", bgl.baglanti());
SqlDataReader dr = komut.ExecuteReader();
while (dr.Read())
{
comboBoxMarka.Properties.Items.Add(dr[1]);
}
bgl.baglanti().Close();
}
I need to save the id value to the database with a button like below:
private void BtnAnaGrupKaydet_Click(object sender, EventArgs e){
SqlCommand komut = new SqlCommand("INSERT INTO ANA_GRUP (marka_id,anagrup_isim,create_date) values (#p1,#p2,#p3)", bgl.baglanti());
komut.Parameters.AddWithValue("#p1", int.Parse(comboBoxMarka.Text));
komut.Parameters.AddWithValue("#p2", txtAnaGrup.Text);
komut.Parameters.AddWithValue("#p3", dateAnaGrup.DateTime);
komut.ExecuteNonQuery();
bgl.baglanti().Close();
MessageBox.Show("Ana Grup Sisteme Eklendi", "Bilgi", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
You can do many implementations.
Use Dataset and after executing your query, you can fill the dataset with the result. so you have all your data in your dataset. (define your database global) and after that when your button hits, you know which index of your combobox is selected. the index is the index of your dataset so you can access the id.
The simplest way is that use a Dictionary with Id and Name. after that is the same above.
To sum up, you need to have a global variable which stores the Id and Name of your query result. this variable can be a Dictionary or a dataset or ....
In order to get selected value instead of text. you would bind combobox like following:
List<DropDownKeyValue> list = new List<DropDownKeyValue>();
List.Add(new DropDownKeyValue
{
ID = 1,
Name = "Designation"
});
cmbSortBy.DisplayMember = "Name";
cmbSortBy.ValueMember = "ID";
cmbSortBy.DataSource = list;
to get selected ID you would use: cmbSortBy.SelectedValue object.
DropDownKeyValue class:
public class DropDownKeyValue
{
public int ID { get; set; }
public string Name { get; set; }
}
You need to bind your ComboBox to a DataSource. The easiest way for you to do this would be to amend your code along these lines:
SqlDataReader dr = komut.ExecuteReader();
var dt = new DataTable();
dt.Load(dr);
yourComboBox.DataSource = null;
yourComboBox.Items.Clear();
yourComboBox.DisplayMember = "brand_name";
yourComboBox.ValueMember = "brand_id";
yourComboBox.DataSource = dt;
You will now be able to access the id using yourComboBox.SelectedValue.
On the line below change values like.
komut.Parameters.AddWithValue("#p1",int.Parse(comboBoxMarka.SelectedValue.ToString()));
Here is my code:
private List<string> readFromDatabase()
{
SQLiteConnection m_dbConnection = new SQLiteConnection("Data Source=" + fileName + ".sqlite;Version=3;");
string sql = "SELECT * FROM formsData";
m_dbConnection.Open();
SQLiteDataReader dr = DatabaseHandler.ExecuteCommandReader(sql, m_dbConnection);
List<string> tempList = new List<string>();
if(dr.HasRows)
{
while (dr.Read())
{
tempList.Add(Convert.ToString(dr["fieldName"]));
tempList.Add(Convert.ToString(dr["dataType"]));
tempList.Add(Convert.ToString(dr["numberOfCharacters"]));
}
}
return tempList;
}
I am trying to make it add each value from the database into the list, however it is only adding the last value found, from the final column. Does anyone know how to solve this? Thank you...
you can use a DataTable instead of DataReader (even though its possible to achieve the same result with DataReader).
please check that discussion: Why is DataTable faster than DataReader.
also its a better practice to use Try-Catchsteatments when connecting to databases.
here is an example (based on your code) how to achieve that task usingDataTable:
private List<string> readFromDatabase()
{
DataTable dt = PullData();
List<string> tempList = new List<string>();
if (dt != null & dt.Rows.Count >0)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
tempList.Add(Convert.ToString(dt.Rows[i]["fieldName"]));
tempList.Add(Convert.ToString(dt.Rows[i]["dataType"]));
tempList.Add(Convert.ToString(dt.Rows[i]["numberOfCharacters"]));
}
}
return tempList;
}
public DataTable PullData()
{
try
{
string connString = #"your connection string here";
string query = "select * from table";
DataTable dataTable = new DataTable();
SqlConnection conn = new SqlConnection(connString);
SqlCommand cmd = new SqlCommand(query, conn);
conn.Open();
// create data adapter
SqlDataAdapter da = new SqlDataAdapter(cmd);
// this will query your database and return the result to your datatable
da.Fill(dataTable);
conn.Close();
da.Dispose();
return dataTable;
}
catch (Exception ex)
{
return null;
}
}
Make sure your record set is positioned at the first row before you start iterating through it.
Also, do you really want to take all the rows of the table and have them as sequential values in a list? Perhaps adding them to class might make more sense.
public class Record{
public string Name { get; set; }
public string Type { get; set; }
public int Size { get; set; }
}
I'm creating a list <object> and here I'm adding my data from a database.
But I totally don't know how to deal with a list <object>.
public class ClassList
{
public int Name { get; set; }
public string Birthday { get; set; }
}
private void GetClassList()
{
SqlConnection conn = new SqlConnection(GlobalVar.ConnString);
SqlCommand cmd = new SqlCommand
("SELECT * " +
"FROM Class_Data ", conn);
conn.Open();
SqlDataReader dr = cmd.ExecuteReader();
try
{
List<ClassList> ClassList = new List<ClassList>();
while (dr.Read())
{
ClassList.Add(new ClassList()
{
Name = ___?___, //what should i write here
Birthday = ___?___ //and here
});
}
}
catch{}
finally
{
dr.Close();
conn.Close();
}
}
Having been looking for lots of information but still fail to work it out.
I will be very appreciated if someone could help!
This should do it:
List<ClassList> ClassList = new List<ClassList>();
while (dr.Read())
{
ClassList.Add(new ClassList()
{
Name = (int)dr["Name"], //the name of the db column
Birthday = dr["Birthday"].ToString();
});
}
As a side note, it maybe worth altering your query from SELECT *... to just selecting the columns you require, from readability/maintenance point of view.
Also, is Name really an int seems like it could be a string.
You can also refer to the documentation:
SqlDataReader.Item Property (String)
You can use column name that are return by your database query with dr like dr["ColumnName"]
ClassList.Add(new ClassList()
{
Name = dr["NameColum"], //what should i write here
Birthday = dr["BrithColum"] //and here
});
Something like that:
// You don't use "this" in the context
// It seems, that you want to return the collected data (List<ClassList>)
private static List<ClassList> GetClassList() {
// Put IDisposable into using
using (SqlConnection conn = new SqlConnection(GlobalVar.ConnString)) {
conn.Connect();
// You want to fetch two fields only, right? Not the entire table (*)
String sql =
#"select Name,
BirthDay
from Class_Data"
using (SqlCommand cmd = new SqlCommand(sql, conn)) {
List<ClassList> result = new List<ClassList>();
using (SqlDataReader dr = cmd.ExecuteReader()) {
while (dr.Read()) {
result.Add(new ClassList() {
Name = Convert.ToString(dr[0]),
Birthday = Convert.ToDateTime(dr[1])
});
}
}
return result;
}
}
}
You can access the column values with dr["ColumnName"].
I have a method which populates my ComboBox from a DataTable:
public string populateCompanyTransSellingEntityLookUp(ref System.Windows.Forms.ComboBox Combo, string Id, Contract Contract)
{
SqlCommand _comm = new SqlCommand();
_comm.Parameters.AddWithValue("#id", Id);
_comm.CommandText = "SELECT [name] FROM dbo.fnGetList(#id) ORDER BY [name]; ";
_comm.Connection = _conn;
_comm.CommandTimeout = _command_timeout;
DataTable dt = new DataTable();
try
{
SqlDataReader myReader = _comm.ExecuteReader();
dt.Load(myReader);
Combo.DataSource = dt;
Combo.DisplayMember = "name";
foreach (DataRow dr in dt.Rows)
{
if (dr["name"].ToString() == Contract.Company_Name.ToString())
{
Combo.Text = dr["company_int_name"].ToString();
}
}
}
catch
{
MessageBox.Show("Unable to populate Company Name LookUp");
}
return "";
}
I'm passing my saved value Contract.Company_Name into the forEach loop to find my required SelectedItem from the DataTable. The ComboBox is populated with my DataTable values from Combo.Datasource =dt; but my selected item isn't being set. The code compiles without exception. If I remove Datasource = dt;, theSelectedItemis set no problem. Why is theDatasourceoverriding mySelectedItem` and is there something I've missed with my binding?
Thanks all
At first you have to set the valueMember for sure. Then you can set the selectedValue Property instead of SelectedItem. The Item is one datasource record. So in your case it would be SelectedItem = dr! But iam not sure this is working.
Try this:
Combo.SelectedItem = dr;
I would suggest to use SelectedValue, then you don't need to loop through values "manually".
Also you don't need to use "heavy-weight" DataTable where you need just a collection of string values.
private IEnumerable<string> LoadNames(string id)
{
var query = "SELECT [name] FROM dbo.fnGetList(#id) ORDER BY [name]";
using (var connection = new SqlConnection("connectionString")
using (var command = new SqlCommand(query, connection)
{
// 36 is the size of the VarChar column in database(use your value)
command.Parameters.Add("#id", SqlDbType.VarChar, 36).Value = id;
connection.Open();
using (var reader = command.ExecuteReader())
{
var names = new List<string>();
while(reader.Read())
{
names.Add(reader.GetString(0));
}
return names;
}
}
}
public void Populate(ComboBox combobox, string id, Contract contract)
{
combobox.DataSource = LoadNames(id);
combobox.SelectedValue = contract.Copmpany_Name.ToString();
}
Few things to notice:
Dispose all objects which dealing with external resources (SqlConnection, SqlCommand and SqlDataReader)
Create SqlParameter with precise information about the type, for strings is important to provide size of the column in database. This information will improve SQL query performance on server side.
Don't pass combobox as a reference, populate method does not create new instance but only consume the given ComboBox instance.
Thank you for the help, I edited the code given that my problem was much more trivial.
public string populate_comboBox(ref System.Windows.Forms.ComboBox Combo)
{
SqlCommand _comm = new SqlCommand();
//edited for a simple one column sql query
_comm.CommandText ="SELECT [Column] FROM dbo.SQL_Table ORDER BY [Column];";
//MUST open sql connection to DB
SqlConnection conn = new SqlConnection(global_DB_String_Connection);
conn.Open();
_comm.Connection = conn;
DataTable dt = new DataTable();
try
{
SqlDataReader myReader = _comm.ExecuteReader();
dt.Load(myReader);
Combo.DataSource = dt;
Combo.DisplayMember = "ColumnName";
foreach (DataRow dr in dt.Rows)
{
//populates the combo box with query results
Combo.Text = dr["ColumnName"].ToString();
}
}
catch
{
Console.WriteLine("ComboBox Populate method has failed! ");
}
conn.Close();
return "";
}
I am sure that someone has asked this before, but I am not searching for the right terms or something because I just can't seem to find what I am looking for.
I have a class Packages:
class Packages
{
string PackageID {get; set;}
string PackageName { get; set; }
}
I have a list of packages in my context.
public class TransferJobContext
{
public string ImportFile;
public string WorkSheetName;
public DataSet TransferData;
public List<Packages> Packages = new List<Packages>();
}
I have a checkedListBox on my form that is bound to a datasource. Here is the section of code where I get the values into the checkedListBox
using (var connection = my_DB.GetConnection())
{
try
{
connection.Open();
SqlDataReader rdr = null;
dt = new DataTable();
string CommandText = "SELECT ID, Name FROM TABLENAME WHERE UPPER(Import_File_Source) LIKE '%abc%' and STATUS = 1";
SqlCommand cmd = new System.Data.SqlClient.SqlCommand(CommandText, connection);
rdr = cmd.ExecuteReader();
dt.Load(rdr);
cbPackages.DataSource = dt;
cbPackages.ValueMember = "ID";
cbPackages.DisplayMember = "Name";
}
catch (Exception E)
{
MessageBox.Show(E.Message.ToString());
}
connection.Close();
}
How do I add a new Package to the list when an item is checked using the value member and displaymember of the selected items?
Edit: Ok maybe I am going about this completely wrong. Instead of telling you what I have done, I'll tell you what I would like to happen.
I am presenting my user with a checkedlistbox that has a list of names with check boxes next to them. They can select more than one. This results in me having one or more ID(s) to use in my query and name(s) to use as a description. I need to pass around with my context the one or many id/name combinations of my "Package".
What is the best what to capture the ID/Name combination of the selections the user made and pass them into my context?
First: Fetch existing Packages from your database:
public function GetPackages() as List<Package>
{
using (var connection = my_DB.GetConnection())
{
try
{
connection.Open();
SqlDataReader rdr = null;
dt = new DataTable();
string CommandText = "SELECT ID, Name FROM TABLENAME WHERE UPPER(Import_File_Source) LIKE '%abc%' and STATUS = 1";
SqlCommand cmd = new System.Data.SqlClient.SqlCommand(CommandText, connection);
var packages = new List<Package>();
using(var reader = cmd.ExecuteReader())
{
do while(reader.Read())
{
packages.Add(new Package({ID = reader.GetString(0), Name = reader.GetString(1)})
}
}
cbPackages.DataSource = packages;
cbPackages.ValueMember = "ID";
cbPackages.DisplayMember = "Name";
return packages;
}
catch (Exception E)
{
MessageBox.Show(E.Message.ToString());
return new List<Package>();
}
connection.Close();
}
}
Second:
Assign the fetched packages to the instance of your context:
yourContext.Packages = GetPackages();
Third:
Fill the CheckedListBox with your packages:
cbPackages.DataSource = yourContext.Packages;
cbPackages.ValueMember = "ID";
cbPackages.DisplayMember = "Name";
Finally: After user input, get the checkedpackages and do whatever you want with them:
foreach (Package item in checkedListBox1.CheckedItems)
{
MessageBox.Show(Package.ID);
MessageBox.Show(Package.Name);
//do whatever you want here e.g. pass it back to the context
}
Sidenote: I would suggest you to rename Packages to Package, PackageID to ID and PackageName to Name (As already proposed in the example code).