I have a datable with column names I0,I1,I2 etc. However these aren't actual column names. I store the column names in another table.
I then have a loop to map the actual column names as follows:
for (int i = 0; i < dt_key.Rows.Count; i++)
{
dt_data.Columns[i].ColumnName = dt_key.Rows[i][0].ToString();
}
I get the following errors:
A column named 'Pressure' already belongs to this DataTable.
and
A column named 'Size' already belongs to this DataTable.
Ultimately I am trying to write this to a xml file:
dt_data.WriteXml(filename);
This works but I end up the column names I0..I22
There are similar questions to this, but they are trying to make datatables with duplicate columns names. I am just trying to print out a table with duplicate column names. What is a good method to do this?
Edit:
I can do the following:
for (int i = 0; i < dt_key.Rows.Count; i++)
{
dt_data.Columns[i].ColumnName = dt_key.Rows[i][0].ToString() + " " + dt_data.Columns[i].ColumnName;
}
I think the short answer to your question is that there is no way to have duplicate column names using a DataTable. What exactly are you using this XML for? There are lots of alternate ways to generate XML that give you a lot more fine grained control.
You could manually create your file using an XmlWriter object. This method creates an XmlWriter that writes to a file.
for (int i = 0; i < dt_key.Rows.Count; i++)
{
if(dt_data.Columns.Contains(dt_key.Rows[i][0].ToString()))
dt_data.Columns[i].ColumnName = dt_key.Rows[i][0].ToString() + " " ;
else
dt_data.Columns[i].ColumnName = dt_key.Rows[i][0].ToString();
}
However adding a same column name is a bad practise,still you could achieve that by adding a space at the end of column name to make it unique.
Maybe you can make use of the DataColumn.Caption property to store the column display name:
https://msdn.microsoft.com/en-us/library/system.data.datacolumn.caption(v=vs.110).aspx
You can not duplicate Column names by using Data Table.Consider this and find another solution .
If you try to duplicate Column name then it will show an error like that you mentioned.
A column named 'Pressure' already belongs to this Data Table .
In here you try to duplicate Column name 'Pressure' that's why that error comes.
Related
I'm working on an autocompleter in c#, I'm using a SQL stored procedure to pull the data which is tested and working.
The issue I'm having is with my for loop which I am using the populate the auto completer.
AutoCompleteStringCollection col = new AutoCompleteStringCollection();
int i = 0;
foreach (DataRow row in TYPESDS.Tables[0].Rows)
{
col.Add(row[i].ToString().ToUpper());
i++;
}
Above is where I have go to with regards to this, I get no errors however the code just does not work.
I have an auto completer working however this has the SQL embedded in the code and I would rather have it working using the stored procedure.
The issue is the use of foreach() to iterate over rows, then for each row also using an indexer (i).
in the original code sample, the "row" in each iteration is a Data Row. The default indexer on this is indexing into the COLUMNS. So on the first row, it'll access column 0, and on the second row, it'll access column 1 and so on.
the second example works because you're using the indexer (i) on the Rows collection property of the table - so this is accessing a ROW. on this Row you're then using the field name indexer to get the "Type" Column.
If the first example was modified to this:
AutoCompleteStringCollection col = new AutoCompleteStringCollection();
foreach (DataRow row in TYPESDS.Tables[0].Rows)
{
col.Add(row["Type"].ToString().ToUpper());
}
Then it is basically equivalent to the second (working) example.
I gave up on using foreach and got it working the following way.
for (int i = 0; i < TYPESDS.Tables[0].Rows.Count - 1; i++ )
{
col.Add(TYPESDS.Tables[0].Rows[i]["Type"].ToString().ToUpper());
}
I think the main issue came with not having the ["Type"] with Rows[i].
i have a small project in c#, in one of my forms i have a datagridview with 3 columns one of the columns is comboboxcolumn that bind with a sql server table id and name, i want to insert the datagridview values into another table in the comboboxcolumn i want to insert the id not a name, anyone can tel me how to do that please? this is my insert code
`
for (int i = 0; i < dgv_student.Rows.Count; i++)
{
sc.add_student(dgv_student.Rows[i].Cells[0].Value.ToString(),
Convert.ToInt32(dgv_student.Rows[i].Cells[1].Value),
dgv_student.Rows[i].Cells[2].Value.ToString());
}
`
the cell[1] the the combobox that display a name not the id.
In your example you have :
Name ID
X X
As your database set. When you are getting this from your database you're probably doing :
myDataGridView.DataSource = GetAllFromMyDatabase(); // Select * from stuff
myDataGridView.DataBind();
Giving you all three columns, and the value. Now, if you want to insert only one column, why not just filter the data you're getting from your database/gridview ?
myComboBox.DataSource = GetOnlyIDFromMyDatabaseOrMyDataGrid(); // Select ID from Stuff
myComboBox.DataBind();
If you're binding your asp.net control with only the data you need, rather than getting everything and then filter, you will have less overhead to think about.
I have a .csv file with around 200 columns and the order of columns changes all the time. I want to read each row from the file, identify the corresponding column names in the database, and write data to the table accordingly.
For this I can use a simple switch case checking for the name of column. Since there are 200 columns, I'm wondering if there is any other way to do it.
Example:
public void ColName(string str, Type a)
{
SampleTableName obj = new SampleTableName();
obj."str" = a;
connection.AddSampleTableName(obj);
connection.savechanges();
}
/* SampleTableName has columns: [Name, Age] */
ColName("Name","XYZ");
Output:
Name Age
XYZ NULL
Any ideas please? Thanks.
If the column names are the same you can use SqlBulkCopy and add a list of Column Mappings. The order doesn't matter, as long as the DataTable name is set.
DataTable table = CreateTable(rows);
using (var bulkCopy = new SqlBulkCopy(connectionString))
{
foreach (var col in table.Columns.OfType<DataColumn>())
{
bulkCopy.ColumnMappings.Add(
new SqlBulkCopyColumnMapping(col.ColumnName, col.ColumnName));
}
bulkCopy.BulkCopyTimeout = 600; // in seconds
bulkCopy.DestinationTableName = "<tableName>";
bulkCopy.WriteToServer(table);
}
If the column names are no the same, a dictionary to lookup the different names could be used.
To keep it simple for maintenance purpose, I went with a switch case sigh. However, I wrote a small script to add all those fields values to the table object.
Background
I have a set of numbers between 1000-9999 split between two data tables both with same the Schema. One data table's schema is then cloned, and then filled with the rows from both of the original tables. This third new data table is then displayed in a datagridview.
Question
How could I then highlight the rows in the datagridview that contain rows from the first data table?
Code
private void combineTables()
{
bothIdsTbl = UsedIdsTbl.Clone();
dataGridView3.DataSource = bothIdsTbl;
for (int i = 0; i <= UnUsedIdsTbl.Rows.Count - 1; ++i)
{
bothIdsTbl.ImportRow(UnUsedIdsTbl.Rows[i]);
}
for (int i = 0; i <= UsedIdsTbl.Rows.Count - 1; ++i)
{
bothIdsTbl.ImportRow(UsedIdsTbl.Rows[i]);
}
dataGridView3.Sort(this.dataGridView3.Columns["stationid"], ListSortDirection.Ascending);
}
The best solution would be the following:
Add a "flag" column to 3rd table before filling it,
Put in that column a value indicating wheteher the row was imported or not from 1st table.
Use the CellFormatting event of the DataGridView to change
cells backcolor according to the flag column.
You can use a command named merge to combine the two datatables.
If this data came from a database you may consider a union query or any other option to combine the data or obtain all the data in one call.
Friends, I'm using datagridviewcomboboxcolumn as column index 1 in my datagridview. I've fetched data from access database table and populated the datagridviewcomboboxcolumn by following manner:
for (int i = 0; reader.Read(); i++)
{
cmbBusCode.Items.Add(reader["BUSINESS_CODE"] + "-" + reader["BUSINESS_DESCRIPTION"]);
cmbBusCode.ValueMember = "BUSINESS_CODE";
}
Then I'm writing this:
cmbBusCode.DisplayIndex = 1;
cmbBusCode.Width = 200;
cmbBusCode.Name = "Code";
cmbBusCode.HeaderText = "Code";
And adding this column as
dgView.Columns.Add(cmbBusCode);
Combobox is being populated and I can select any one from the list. Now when I'm saving data I want to get the ValueMember of the selected item. To get this value I'm using following code but It's giving the string representation of the field "BUSINESS_CODE" not the value..Please help me so that get ValueMemeber of the selected item..
foreach (DataGridViewRow row in dgView.Rows)
{
string cd = row.Cells["Code"].Value.ToString();
}
The "item" you are adding to the column doesn't have a "BUSINESS_CODE" column (essentially, the item as you add it is simply a string), so that doesn't work.
What you need to do is assign items that contain multiple columns. One must be the BUSINESS_CODE column (as it is this column you want to be the value for the underlying field in the DataGridView), the other should be a display column that contains the concatenated value you're adding at the moment (DisplayMember and ValueMember).
Easiest would be to create a typed data set, add a table that contains the two columns I described and fill the table with the data from the data reader.
Then, add the table as the data source for the column.
You can try adding a DataGridViewComboBoxCell instead of a string to the cmbBusCode.Items collection. You can then specify Value in the cell. I'm not sure if this will work, but it's worth a try.