I am trying to get a value from a DataRow in a specific column in a DataTable. It should return values like "abc12345", but instead returns "ListViewSubItem: {abc12345}", according to the debugger. Why is this?
foreach (DataRow row in itemsTable.Rows)
{
// the required data is in the first column of the DataTable
// both of the following have been tried:
string myValue = row[0].ToString();
string myValue = row.Field<string>(0);
}
You are doing it wrong. It should be string myValue = row[columnIndex].Text; and you are trying to get the value of the first column. You can use row["columnName"] also .
Note: I have used Text property.
Related
Is it possible to get a row value by giving column name when DataTable holds a single row, without iteration.
foreach(DataRow row in dt.Rows)
{
string strCity = row["City"].ToString();
}
Table
I need Something like below without loop when we have only one row,
String cn=row["ColumnName"].ToString()
This is the way:
string Text = dataTable.Rows[0]["ColumnName"].ToString();
Use following code to get the value of the first row of the DataTable without iteration:
string strCity = string.Empty;
if (yourDataTable.Rows.Count > 0)
strCity = yourDataTable.Rows[0]["City"].ToString();
Convert.ToString(row["ColumnName"]);
This is attempting to index the row itself:
row["ColumnName"].ToString()
What you're looking for is to index the items within the row:
row.Item["ColumnName"].ToString()
when DataTable holds a single row, without iteration
If you're guaranteed that there is a row, you can reference it directly:
dt.Rows[0].Item["ColumnName"].ToString()
As with any indexing, you should probably do some bounds checking before trying to index it though.
DataTable dt = new DataTable();
sqlDa.Fill(dt);
if (dt.Rows.Count > 0)
{
StringBuilder html = new StringBuilder();
foreach (DataRow row in dt.Rows)
{
html.Append(row.Field<Int32>("Columname"));
}
}
I have a datatable with columns a,b,c,d,e.
When column b is null, I want to set its value to the value of column a and then set all the other columns for that particular row to an empty string.
Try this:
System.Data.DataRow r = dt.Rows[0];
if ( r["b"] == System.DbNull.Value ) //DbNull assumes the nulls are coming from DB. If they are set to null via your code then you can use good old null instead.
{
r["b"] = r["a"];
r["c"] = "";
r["d"] = "";
}
Is it possible to use GetSchemaTable() to retrieve only column names?
I have been trying to retrieve Column names (only) using this method, is it possible.
DataTable table = myReader.GetSchemaTable();
foreach (DataRow myField in table.Rows)
{
foreach (DataColumn myProperty in table.Columns)
{
fileconnectiongrid.Rows.Add(myProperty.ColumnName + " = "
+ myField[myProperty].ToString());
}
}
This code retrieves a lot of table data unwanted, I only need a list containing
column names!:
You need to use ExecuteReader(CommandBehavior.SchemaOnly)):
DataTable schema = null;
using (var con = new SqlConnection(connection))
{
using (var schemaCommand = new SqlCommand("SELECT * FROM table", con))
{
con.Open();
using (var reader = schemaCommand.ExecuteReader(CommandBehavior.SchemaOnly))
{
schema = reader.GetSchemaTable();
}
}
}
SchemaOnly:
The query returns column information only. When using SchemaOnly, the
.NET Framework Data Provider for SQL Server precedes the statement
being executed with SET FMTONLY ON.
The column name is in the first column of every row. I don't think that it's possible to omit the other column informations like ColumnOrdinal,ColumnSize,NumericPrecision and so on since you cannot use reader.GetString but only reader.GetSchemaTable in this case.
But your loop is incorrect if you only want the column names:
foreach (DataRow col in schema.Rows)
{
Console.WriteLine("ColumnName={0}", col.Field<String>("ColumnName"));
}
Change your code to below if all you want is to display the column names. Your original code was trying to not only display column names, but also trying to display the actual data values as well.
DataTable table = myReader.GetSchemaTable();
foreach (DataRow myField in table.Rows)
{
foreach (DataColumn myProperty in table.Columns)
{
fileconnectiongrid.Rows.Add(myProperty.ToString());
}
}
This will give you all column names, you can place them in a string[] and do with them what you like.
foreach(var columnName in DataTable.Columns)
{
Console.WriteLine(columnName);
}
//Retrieve column schema into a DataTable.
schemaTable = reader.GetSchemaTable();
int index = schemaTable.Columns.IndexOf("ColumnName");
DataColumn columnName = schemaTable.Columns[index];
//For each field in the table...
foreach (DataRow myField in schemaTable.Rows)
{
String columnNameValue = myField[columnName].ToString();
Console.WriteLine("ColumnName " + columnNameValue);
}
I use same technics to add MAX-STRING-LENGTH constraint on custom TextBox in my VB.Net program.
I use a SQL SELECT command to get 4 column's values
SELECT code_pays
,nom
,code_pays_short
,default_devise
FROM pays
ORDER BY nom
I use the result returned by an IDataReader object to fill a DataGridView.
And finally, I display each row's field in a Panel that contains 4 TextBox.
To avoid that SQL UPDATE command used to save some record's changes done in TextBox return error message due to column value too long, I have added a property in custom Textbox to inform directly user that value's size is overlapped.
Here is my Form
Here is VB.Net code used to initialize MaxStringLength properties
Private Sub PushColumnConstraints(dr As IDataReader)
Dim tb As DataTable = dr.GetSchemaTable()
Dim nColIndex As Integer = -1
For Each col As DataColumn In tb.Columns
If col.ColumnName = "ColumnSize" Then
nColIndex = col.Ordinal
Exit For
End If
Next
If nColIndex < 0 Then
oT.ThrowException("[ColumnSize] columns's index not found !")
Exit Sub
End If
txtCodePays.MaxStringLength = tb.Rows(0).Item(nColIndex)
txtPays.MaxStringLength = tb.Rows(1).Item(nColIndex)
txtShortCodePays.MaxStringLength = tb.Rows(2).Item(nColIndex)
txtDefaultDevise.MaxStringLength = tb.Rows(3).Item(nColIndex)
End Sub
In For loop, program search index of field contained in ColumnSize column's value.
MaxStringLength property is assigned using following syntax
tb.Rows(%TEXT-BOX-INDEX%).Item(nColIndex)
.Rows(%TEXT-BOX-INDEX%) is used to identify column's metadata in SQL SELECT !
.Item(nColIndex) is used to get a specific column's metadata value
Item(n) can return a String or an Integer but VB.Net do implicit conversion when necessary.
This line of code can also be written shortly
tb.Rows(%TEXT-BOX-INDEX%)(nColIndex)
tb(%TEXT-BOX-INDEX%)(nColIndex)
but it is not readable !
Caution: MaxStringLength is a custom property. It is not part of normal TextBox.
In print screen above, you can see that program indicates to user that length is too big for Code Pays (3 lettres) TextBox.
Error's message is displayed in StatusBar at bottom of Form.
This information is displayed before clicking on SAVE button that generates an SQL UPDATE command.
Code used that call PushColumnConstraints method is following
Public Sub FillPanel()
SQL =
<sql-select>
SELECT code_pays
,nom
,code_pays_short
,default_devise
FROM pays
ORDER BY nom
</sql-select>
Dim cmd As New NpgsqlCommand(SQL, cn)
Dim dr As NpgsqlDataReader
Try
dr = cmd.ExecuteReader()
Catch ex As Exception
ThrowException(ex)
End Try
Call PushColumnConstraints(dr)
I have some code which sets the value of cells in a DataRow by column name i.e.
row["ColumnName"] = someValue;
I want to also set the value for this row in the column immediately to the right of the one found above. Clearly if I was getting the cell by index rather than by column name this would be easy. So is there a way of getting the column index from the column name thus allowing me to do:
row[index + 1] = someOtherValue;
i.e. do I need create some kind of dictionary of column index and column names when the table is initially created, or can I get the index from the column name later on without doing this?
You can use DataColumn.Ordinal to get the index of the column in the DataTable. So if you need the next column as mentioned use Column.Ordinal + 1:
row[row.Table.Columns["ColumnName"].Ordinal + 1] = someOtherValue;
Warning:
This code returns the next column, so the one after ColumnName, as requested in the question.
Try this:
int index = row.Table.Columns["ColumnName"].Ordinal;
You can simply use DataColumnCollection.IndexOf
So that you can get the index of the required column by name then use it with your row:
row[dt.Columns.IndexOf("ColumnName")] = columnValue;
I wrote an extension method of DataRow which gets me the object via the column name.
public static object Column(this DataRow source, string columnName)
{
var c = source.Table.Columns[columnName];
if (c != null)
{
return source.ItemArray[c.Ordinal];
}
throw new ObjectNotFoundException(string.Format("The column '{0}' was not found in this table", columnName));
}
And its called like this:
DataTable data = LoadDataTable();
foreach (DataRow row in data.Rows)
{
var obj = row.Column("YourColumnName");
Console.WriteLine(obj);
}
I have a problem with assigning string array into Datarow. Firstly, i have created the object for string array and put 2 values in the array out of 100(whole size). How many values should be placed in the array dependds on a different, which i am not showing here, though.
Then i tried converting into DataRow. But it says. "object reference not set to an instance of an object"
DataRow dr = null;
string[] strconcat = new string[100];
dr["concat"] = strconcat[i];
Thanks in advance
Edit-- Actually i was trying put these string array values into dropdown (ddchooseadeal). Is there any other good way other than this.
locname = ddchoosealoc.SelectedValue.ToString();
string[] strdeals = new string[100];
string[] strconcat = new string[100];
int i;
for(i =0; i< dsdeal.Tables[0].Rows.Count; i++)
{
strdeals[i] = Convert.ToString( dsdeal.Tables[0].Rows[i]["Title"]);
strconcat[i] = strdeals[i]+" -- "+ locname;
}
DataRow dr = null;
ddchooseadeal.Items.Clear();
ListItem li = new ListItem("Choose a Deal");
ddchooseadeal.Items.Add(li);
dr["drconcat"] = strconcat[0];
ListItem item = new ListItem();
item.Text = NullHandler.NullHandlerForString(strconcat[i], string.Empty);
ddchoosealoc.Items.Add(item);
Your DataRow is not a part of any DataTable which is actually right, that's why you can't instantiate a direct DataRow object.
So that's the theory part, to solve your problem
// Declare a DataTable object.
DataTable dt = new DataTable();
// Add some columns to the DataTable
dt.Columns.Add("StringHolder");
// Now suppose , you are having 10 items in your string array
foreach(string str in strArray)
{
DataRow drow = dt.NewRow() ; // Here you will get an actual instance of a DataRow
drow ["StringHolder"] = str; // Assign values
dt.Rows.Add(drow); // Don't forget to add the row to the DataTable.
}
So by following the above steps, you will have a DataTable populated with rows.
Your string array here has 100 elements, all null. So if you assign one of the elements into your data row, you are assigning null. Not a string.
If you are creating an array, the elements will remain uninitialised until you populate it with something. Value types will have their default value (0 for int, false for bool, etc.) while reference types (like string) default to null.
Also, dr is set to null in your example.
You are attempting to add values to a variable that is null DataRow dr = null; which is why you are getting the "object reference not set to an instance of an object" error.
You need to create a new datarow using your DataTable object, then adding the values to that DataRow. Without seeing more of the code it would be hard to offer much more help, but the following article from MSDN will get you started:
How to: Add Rows to a DataTable
check with your debugger if your desired column exists:
var x = dr["concat"];
and check if your desired value exists in the string array with:
var y = strconcat[i];
your datarow above is initialized with null so the error message is absolutely plausible.
you have to design a datatable with the columns you want. after that get a new row from that table and save the values from your string array to the datarow.
see msdn: how to add rows to a datatable => http://msdn.microsoft.com/en-us/library/5ycd1034%28VS.80%29.aspx
It throws NullPointerException because dr is null, you have to create dataRow with DataTable.NewRow Method
Building off Saurabh's answer, you can build a DataTable and it's columns and add each DataRow.
But there is a constructor for the DataRow that takes a params object[] values. So you can automatically add a whole string array to a DataRow, provided that the order of the elements matches the order of the columns specified:
// Create the data table
var dataTable = new DataTable("TableName");
// Add the columns you will need
dataTable.Columns.Add("FirstName");
dataTable.Columns.Add("LastName");
dataTable.Columns.Add("Whatever");
// Get your data in string array format
// Will need to be FirstName, LastName, Whatever
string[] data = LoadStringArrayFromCsvOrSomething();
// Add the DataRow using the string array
dataTable.Rows.Add(data);
This works great in conjunction with the Microsoft.VisualBasic.FileIO.TextFieldParser and the System.Data.SqlClient.SqlBulkCopy. You can throw data into SQL Server like its nobody's business.