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.
Related
var itemAmountList = _itemAmountvalue.Split(',');
var listItemDescriptionValues = _itemDescriptionvalue.Split(',');
IEnumerator enum1 = itemAmountList.GetEnumerator();
IEnumerator enum2 = listItemDescriptionValues.GetEnumerator();
DataTable dtCustomInvoiceDetail = new DataTable();
dtCustomInvoiceDetail.Columns.Add("purchaseOrderID");
dtCustomInvoiceDetail.Columns.Add("itemAmount");
dtCustomInvoiceDetail.Columns.Add("itemDescription");
while ((enum1.MoveNext()) && (enum2.MoveNext()))
{
var description = enum1.Current;
var amount = enum2.Current;
DataRow dr = dtCustomInvoiceDetail.NewRow();
dr["itemDescription"] = description;
dr["itemAmount"] = amount;
dr["purchaseOrderID"] = strPoid;
}
Above is the code that I am using to iterate through a list and populate a datatable.
I do not see any rows added to the datatable
Verified the data and looks good
it iterates through the loop the no of times as required
But still do not see any data in the datatable
In your code
DataRow dr = dtCustomInvoiceDetail.NewRow();
does not actually add a row to the table, it only creates a table row with the correct columns. In order to add the row you need to call
dtCustomInvoiceDetail.Rows.Add(dr)
at the end
the problem is that you are not adding the generated row to datatable.
Datatable.NewRow :
You must use the NewRow method to create new DataRow objects with
the same schema as the DataTable. After creating a DataRow, you
can add it to the DataRowCollection, through the DataTable
object's Rows property
you should add the row to your datatable like this
dtCustomInvoiceDetail.Rows.Add(dr);
also note that you can convert the whole enumerator logic to a simple for loop, it has more readability and less overhead
for (int i = 0; i < Math.Min(itemAmountList.Count, listItemDescriptionValues.Count); i++)
{
var description = itemAmountList[i];
var amount = listItemDescriptionValues[i];
DataRow dr = dtCustomInvoiceDetail.NewRow();
dr["itemDescription"] = description;
dr["itemAmount"] = amount;
dr["purchaseOrderID"] = strPoid;
}
also it seems that there is an inconsistency between names and variable assignments. you assign a value from listItemDescriptionValues to amount variable and from itemAmountList to description. Please double check it.
I have a datatable and a row. I want to import the row to the datatable only if it does not exist in the datatable.
How can i do that?
If you use a typed DataSet, I.e. declared in design time, the "linq Contains method" takes a typed DataRow. The default IEqualityComparer will compare all values in the DataRow. (Which is normally useless, since you should have a key defined).
DataSet1 ds = new DataSet1();
DataSet1.DataTable1Row row = ds.DataTable1.AddDataTable1Row(bla, bla);
bool exists = ds.DataTable1.Contains(row);
You can use LINQ to check if row is present in datatable. Follow this solution, and replace "id" with your row's primary key, by which you can uniquely identify a row in a table.
DataRow dr = null; // assign your DR here
DataTable dt = new DataTable(); // assign Datatable instance here.
var k = (from r in dt.Rows.OfType<DataRow>() where r["id"].ToString() == dr["id"].ToString() select r).FirstOrDefault();
if(k != null)
{ // Row is present }
if you want to check all the cells in a DataRow, you can try this function:
bool ContainDataRowInDataTable(DataTable T,DataRow R)
{
foreach (DataRow item in T.Rows)
{
if (Enumerable.SequenceEqual(item.ItemArray, R.ItemArray))
return true;
}
return false;
}
you can use Contains as below
if(DataTable.Columns.Contains("RowName"))
{
//Do some stuffs here
}
Tried all answers here but did not work, so I made something for myself which works in my case. The code is pretty simple, it checks if the row you want to add already exists in the datatable - if it does not exist in the datatable, add it.
// fill dt with information
DataTable dt = new DataTable();
// create a new row and fill it with information
DataRow dr = dt.NewRow();
// distinct
bool isDistinct = true;
for (int i=0; i < dt.Rows.Count; i++)
{
// check if both rows are equal
if (Enumerable.SequenceEqual(dt.Rows[i].ItemArray, dr.ItemArray))
{
// it already exists
isDistinct = false;
break;
}
}
if (isDistinct)
{
dt.Rows.Add(dr);
}
if ( Datatable1.Rows[NumOfRow].ToString().Deleted == "Deleted")
You should check row existence by comparing primary keys:
static bool RowExists(DataTable table, DataRow row)
{
var pk = table.PrimaryKey
.Select(column => row[column, DataRowVersion.Original])
.ToArray();
return table.Rows.Contains(pk);
}
Reason is, DataRow that you are trying to check against existing DataTable is, in real-life scenarios, different class instance compared to the DataRaw in the table, even when same DataRaw already exists in the DataTable. Usual .NET equality-comparison does not work properly in this scenarios. That includes DataTable.Contains(...) method.
To properly check for DataRaw existence in the table, primary key given DataRaw should be searched for in the table.
You can check using any with the key value
If (value.Tables(0).AsEnumerable().Any(Function(x) key = x.Field(Of Integer)("ProductId") ))
I have a DataTable, which I construct in the following way:
DataTable data = new DataTable();
data.Columns.Add("year");
data.Columns.Add("month");
data.Columns.Add("id");
data.Columns.Add("displayText");
data.Columns["displayText"].Expression = "Convert(year, 'System.String') + ' / ' + Convert(month , 'System.String')";
DataColumn[] keyColumns = new DataColumn[2];
keyColumns[0] = data.Columns["year"];
keyColumns[1] = data.Columns["month"];
data.PrimaryKey = keyColumns;
data is used as a data source for the monthList drop down list
this.monthList.DataTextField = "displayText";
this.monthList.DataValueField = "id";
this.monthList.DataSource = data;
this.monthList.DataBind();
Then I have an event handler, in which I need to extract both components of the key column.
How can I do that?
I tried to use monthList.SelectedItem.Value, but it contains a string "System.Object[]".
Update 1: Here's the debugger's screenshot.
Update 2: Here's how I add items to data:
var row = data.NewRow();
row["year"] = 2014;
row["month"] = 5;
row["id"] = new object[] { 2014, 5 };
data.Rows.Add(row);
Not sure why you are trying to store an array in your id field considering that the same values are stored in the same row but in different columns, but you could extract the values in that field if you declare your column of type object
data.Columns.Add("id", typeof(object));
and then retrieve them with
object[] ids = (object[])data.Rows[0]["id"];
for(int x = 0; x < ids.Length; x++)
Console.WriteLine(Convert.ToInt32(ids[x]));
You have set:
this.monthList.DataValueField = "id";
Therefore the Value property will be set to the value of the "id" column in your DataTable.
The "id" column in your DataTable is defined (by default) as type "String", but you've set it to an object array:
row["id"] = new object[] { 2014, 5 };
The column will actually contain
(new object[] { 2014, 5 }).ToString();
which is the string you're seeing.
You could try declaring the id column as type object[]:
dt.Columns.Add("id", typeof(object[]));
After which you should be able to cast monthList.SelectedItem.Value to object[] and extract your two values.
Having said that: personally I would probably put the two values composing the id into separate int columns.
It seems that binding a column that contains collection of objects to DataValueField property of DropDownList is not supported by design(it makes value attribute of option tag to be set to collection type name).
You could try to dump collection objects to a single string value and use that string value as a key...
For example:
row["id"] = "2014_05";
EDIT:
Of course you may calculate this key value automatically using the same feature as you used for displayText column:
data.Columns["id"].Expression = "Convert(year, 'System.String') + '_' + Convert(month , 'System.String')";
I am attempting to loop through a dataset's rows and columns in search for a match between the dataset's name column -- and the ColumnName from a DataReader object.
I have a new table called RECORDS which is empty at program startup. I also have a pre-populated table called ColumnPositions with a sub-set of column names found in the RECORDS table. This routine is intended to show a subset of all the available columns -- as a default display style.
My code works...except for the line of code that gets the dr["type"] value. I get the error:
The name 'colType' does not exist in the current context.
As you can clearly see, my string variables are declared outside the WHILE and FOREACH loops. The line statement colName = works just fine. But colType fails everytime. If I do a statement check in the Intermediate Window in VS2010 for ? dr["type"]" I get the result integer. But when I check ? colType, I get the above noted error message.
The intellisense for the DataRow object dr reveals an array of 6 items. Index 1 in the array maps to name. Index 2 maps to type. When I check the value of ? dr[2] in the Intermediate Window, the same result comes back integer. This is correct. But whenever this value is assigned to colType, VS2010 complains.
I'm no newbie to C# so I did a lot of testing and Googling before posting here. I'm hoping that this is a matter of me not seeing the forest through the trees.
Here's my code:
// get table information for RECORDS
SQLiteCommand tableInfo = new SQLiteCommand("PRAGMA table_info(Records)", m_cnCaseFile);
SQLiteDataAdapter adapter = new SQLiteDataAdapter(tableInfo);
DataSet ds = new DataSet();
adapter.Fill(ds);
DataTable dt = ds.Tables[0];
SQLiteCommand cmd = new SQLiteCommand("SELECT * FROM ColumnPositions WHERE ColumnStyle_ID = " + styleID + " ORDER BY ColumnPosition_ID ASC", m_cnCaseFile);
SQLiteDataReader colReader = cmd.ExecuteReader();
string colName = "";
string colType = "";
if (dt != null && colReader.HasRows)
{
while (colReader.Read())
{
foreach(DataRow dr in dt.Rows)
{
colType = Convert.ToString(dr["type"]);
colName = dr["name"].ToString();
if (colReader["ColumnName"].ToString() == colName)
{
DataGridViewColumn dgvCol = new DataGridViewColumn();
}
}
}
}
dt.Dispose();
colReader.Close();
Instead of using "dr["name"].ToString();", it is better to use "Convert.ToString(dr["name"]);"
Try using the array position instead of the column name:
colType = Convert.ToString(dr[1]);
and
colName = dr[0].ToString();
You probably don't need this, but here is the documentation for values returned by the SQLite PRAGMA table_info() command. LINK
DataSet dsUdpated = new DataSet()
DataTable dtUpdated = dsUpdated.Tables.Add();
dtUpdated = dsOriginal.Tables[0].Clone(); // Guarenteed ds.Tables[0] has rows
dsUpdate.Tables[0].ImportRow(row); // row is one of the filtered row in
But the ImportRow doesnt seem to add the rows!. dsUpdate.Tables[0] doesnt contain the row. But a row is added. Please help!
Here's what you're doing wrong.
DataTable dtUpdated = dsUpdated.Tables.Add();
dtUpdated = dsOriginal.Tables[0].Clone();
In the first line, you are declaring your object and initializing it to the result of an Add operation on the DataSet's Tables collection. In the second line, you are setting to to something else entirely!
dtUpdated may very well refer to the same object in memory as dsUpdated.Tables[0] after the first line of code, but the variable itself is not a constant reference to that object. Indeed, in the second line, you have set it to a different object, the result of another table's Clone() method. If the variable ever pointed to the same object as dsUpdated.Tables[0], it does not anymore. It's similar to stating
int x = 5;
x = 6;
In the first line, the value of x is 5. In the second, you've replaced that value with 6. Similarly, with your table variable, the value is a reference. You've replaced one reference with another. Make sense?
Clone the table first, then add that table to the dataset. Now dsUpdated.Tables[0] will contain the cloned structure of dsOriginal.Tables[0] and your import should work as expected.
Please try this:
DataTable dt=dsOriginal.Tables[0].Clone();
dsUpdated.Tables.Add(dt);
DataTable dtUpdated=dt;
Please clone the DataTable first.
DataTable dt=table.Clone();
foreach (DataRow row in table.Select("AirAvail_Id=0"))
{
dtAirAvail.ImportRow(row);
}
This will work fine.