Column abc does not belong to table? - c#

I am iterating a DataTable in my C# code. I try to get the contents using of a column named "columnName" of row named "row" using -
object value = row["ColumnName"];
I get this error -
Error: System.Reflection.TargetInvocationException: Exception has been
thrown by the target of an invocation.
---> System.ArgumentException: Column 'FULL_COUNT' does not belong to table . at System.Data.DataRow.GetDataColumn(String columnName)
How is this possible ? My SQL query/result set has a column by that name and the query even runs in management studio.
How do I fix this error ?

I am guessing your code is iteration supposed to be something like this
DataTable table = new DataTable();
foreach (DataRow row in table.Rows) {
foreach (DataColumn col in table.Columns) {
object value = row[col.ColumnName];
}
}
If this is the case, row["ColumnName"] in each iteration looks for the same column with name ColumnName which obviously does not exists in your table.
The correct way is row[ColumnName] or row[col.ColumnName] in iteration above

I had a similar issue on my c# code, using a dataset which I had successfully initialized and populated with data from the DB.
So my return set was:
data = new Byte[0];
data = (Byte[])(dataset.Tables[0].Rows[0]["systemLogo_img"]);
Of course the error was in t finding the column 'systemLogo_img'.
I noted that you simply do NOT have to call /qualify the column name. So the correction is:
data = new Byte[0];
data = (Byte[])(dataset.Tables[0].Rows[0].ItemArray[0]);
Simply put: use "ItemArray" at position.
Thanks

Do not write Gridview column names instead of Database column names.
dataGridViewEmployeeClass.Rows[n].Cells[0].Value = item["write the Database Column names"].ToString();

Try this, make sure your column name is same
DataTable dt = new DataTable();
dt.Columns.Add("abc", typeof(string));
DataRow dr = dt.NewRow();
dr["abc"]="";

I had a similar issue which was very basic to fix.
I was querying with a specific column name rather than Select * (i.e. Select Title). Beginner's error but happens to everyone.

If you want to check if the column exists in the DataRow before accessing the value the following block can help...
if (dataRow.Table.Columns.Contains("theColumnName"))
{
// do work
string text = string.Empty;
if (dataRow["theColumnName"] != System.DBNull.Value)
{
text = Convert.ToString(dataRow["theColumnName"]);
}
}
If it doesn't exist and it needs to be added to the data table you can add the column using #Karthick Ganesan's example
// add a column
dataTable.Columns.Add("theColumnName", typeof(string));

I had same issue was trying to pass two different keys for same product.
item.Product = SqlHelper.GetSafeString(dr, "ProductName");
item.Product = SqlHelper.GetSafeString(dr, "Product");

Related

DataRow Column Has Value When Read One Way, But Not When Read a Different Way

I'm trying to read values from a DataSet in C#/ASP.NET returned from a stored procedure. Normally, the DefaultView from that DataSet is passed into a GridView in an ASP.NET page. in that event, a particular column I'm interested in has a value. However, if I try to read a DataRow and get the column value, it comes through as empty.
For example, this will display a value:
DataSet ds = //////
DataView dv = ds.Tables[0].DefaultView;
grdQuotes.DataSource = dv;
grdQuotes.DataBind();
This, however, gives me no value:
DataSet ds = //////
foreach (DataRow row in ds.Tables[0].Rows) {
String value1 = (String)row["DOReviewDate"];
String value2 = ((Object)row["DOReviewDate"]).ToString();
String value3 = row.Field<String >("DOReviewDate");
}
All three variables end up empty.
I'm pretty lost on where to go with this, as it's apparent that there's a value being pulled from the SQL database, otherwise it wouldn't display in the GridView table on the page. Also, I can get the rest of the column values in the row without problem. Interestingly enough, there is one other column exhibiting the same behavior.
-- EDIT --
Attempt to iterate through rows and columns to get data:
StringBuilder sb = new StringBuilder();
foreach (DataRow row in ds.Tables[0].Rows)
{
StringBuilder r = new StringBuilder();
foreach (DataColumn c in ds.Tables[0].Columns)
{
r.Append(String.Format("{0} | ", row[c]));
}
r.Append("END");
sb.AppendLine(r.ToString());
}
I was finally able to locate the stored procedure powering this functionality. It's returning empty values for the columns I need. There's nothing but an empty string designating what to return. So, while I can't seem to find the functionality within the page construction, it looks like there is some sort of join or alternate search pulling the data, and I believe I found the table to pull from. Guess I'll just have to take this initial data returned to me and use it to pull from the other table. Or, I guess, maybe make my own SQL search with a join. Either way, the stored procedure does not itself contain a join to the table I need. This is what was in the stored procedure:
'' as DOReviewDate

Set constant value to some columns in SqlBulkCopy

I'm trying transfer data from "csv" file to SQL Database. Is it possible to map some fields by default vale which not exsits in "csv" file?
Something like shown below:
bulkCopy.ColumnMappings.Add("Destenition_column_name", "constant_value");
Thanks for advance!
What about setting a default column BEFORE populating the DataTable?
var returnTable = new DataTable();
returnTable.Columns.Add("Constant_Column_Name").DefaultValue = "Constant_Value";
If you then add rows each row will always have the specified default value for this column without explicitly setting it.
Anytoe's answer can be useful if you create DataTable by yourself. But there could be a situation when you are getting the dataTable from some library method so you trick with default value will not work. For this case I found this solution:
var dt = await GetDataTable();
dt.Columns.Add("ImportFileId", typeof(long), importFileId.ToString());
This is a feature named "Expression Columns". For example, you can use this solution with the ExcelDataReader library which has ".dataset()" method.
And you always can just loop through the rows if you don't want to use "Expression Columns" :
foreach (DataRow dr in dt.Rows)
{
dr["ImportFileId"] = importFileId.ToString();
}
Info: https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/dataset-datatable-dataview/creating-expression-columns

why can't I pass the name of the table to get the table from DataSet.tables?

I have a custom table. Here is the information about the custom table. Here are the names of the table
Table Name : customtable_TwitterCacheTable
Why can't I access the table by using the Table Name,
so in my code, if I do this, I will get a NullReference Exception
foreach (DataRow row in ds.Tables["customtable_TwitterCacheTable"].Rows)
{
CustomTableItem deleteItem = new CustomTableItem(row, customTableClassName);
deleteItem.Delete();
}
But the following seems work OK
foreach (DataRow row in ds.Tables[0].Rows)
Why can't I pass the name of the table in to get a table? Do I have to use this index based approach?
Please let me know.
Thanks
You need to manually name the table in the dataset. Unless its excplicitly named, its only known as ds.tables[0]. Depending on how you get the data you could:
//if you used a SqlDataAdapter
da.Fill(ds, "customtable_TwitterCacheTable");
Or you could do this:
ds.Tables[0].TableName = "customtable_TwitterCacheTable";

Remove row from generic datatable in C#

I ran into a problem trying to remove a row from a datatable in C#. The problem is that the datatable is built from SQL, so it can have any number of columns and may or may not have a primary key. So, I can't remove a row based on a value in a certain column or on a primary key.
Here's the basic outline of what I'm doing:
//Set up a new datatable that is an exact copy of the datatable from the SQL table.
newData = data.Copy();
//...(do other things)
foreach (DataRow dr in data.Rows)
{
//...(do other things)
// Check if the row is already in a data copy log. If so, we don't want it in the new datatable.
if (_DataCopyLogMaintenance.ContainedInDataCopyLog(dr))
{
newData.Rows.Remove(dr);
}
}
But, that gives me an error message, "The given DataRow is not in the current DataRowCollection". Which doesn't make any sense, given that newData is a direct copy of data. Does anyone else have any suggestions? The MSDN site wasn't much help.
Thanks!
Your foreach needs to be on the copy, not the original set. You cannot remove an object contained in collection1 from collection2.
foreach (DataRow dr in newData.Rows)
Otherwise you could use a counter to remove at an index. Something like this:
for(int i = 0; i < data.Rows.Count; i++)
{
if (_DataCopyLogMaintenance.ContainedInDataCopyLog(data.Rows[i]))
{
newData.Rows.RemoveAt(i);
}
}

How can I add the column data type after adding the column headers to my datatable?

Using the code below (from a console app I've cobbled together), I add seven columns to my datatable. Once this is done, how can I set the data type for each column? For instance, column 1 of the datatable will have the header "ItemNum" and I want to set it to be an Int. I've looked at some examples on thet 'net, but most all of them show creating the column header and column data type at once, like this:
loadDT.Columns.Add("ItemNum", typeof(Int));
At this point in my program, the column already has a name. I just want to do something like this (not actual code):
loadDT.Column[1].ChangeType(typeof(int));
Here's my code so far (that gives the columns their name):
// get column headings for datatable by reading first line of csv file.
StreamReader sr = new StreamReader(#"c:\load_forecast.csv");
headers = sr.ReadLine().Split(',');
foreach (string header in headers)
{
loadDT.Columns.Add(header);
}
Obviously, I'm pretty new at this, but trying very hard to learn. Can someone point me in the right direction? Thanks!
You should be able to assign the column's data type property so long as there is no data stored in that column yet:
CODE:
loadDT.Column[1].DataType = typeof(int);
visual studio not allows to change type of a column has some data,
u must create a new column with ur ideal type and copy data from specified column to new column
DataTable DT = new DataTable();
DT = somsdata ;
DT.columns.Add("newcol",object);
foreach(datarow dr in DT.rows)
dr.itemarray["newcolumn"] = dr.itemarray["oldColumn"];

Categories