how to update datarow in datatable using LINQ C#? - c#

i want to update datatable(dtTaskandBugs) on some condition.
want to update storyid of all the row in the datatable when the id(which is a column of the Datatable) is passed as paramter to the function GetStoryid.
this is my code below it's not working (nothing happening)
dtTaskandBugs.Select(string.Format("Storyid = '{0}'", dtTaskandBugs.Rows)).ToList<DataRow>().ForEach(
r =>
{
r["Storyid"] = GetStoryid(r["Id"]);
});

The error is here:
string.Format("Storyid = '{0}'", dtTaskandBugs.Rows)
You are passing the number of rows in this table as argument to DataTable.Select which filters the rows, so probably doesn't return any rows.
I suggest a simple foreach-loop since you want to update all rows:
foreach(DataRow row in dtTaskandBugs.Rows)
row ["Storyid"] = GetStoryid(row["Id"]);

Related

How to add new column to DataTable with auto index of row (C#)

I have a Datatable, and I need to add "id" or "index" column with auto value.
like a identity column in sql.
I have a function that return me the start index: GetID();
I need that the value of this column in the first row will be the value that GetID() return, the value in the second row will be GetID() + 1.... GetID() + 2 ...
I need to do this without loops .
I thought to use "Expression" when I create new column, but I dont know how to do this.
You can use AutoIncrement property of DataTable column:
var dt = new DataTable();
var col = dt.Columns.Add("ID", typeof (long));
col.AutoIncrement = true;
col.AutoIncrementSeed = GetID();
col.AutoIncrementStep = 1;
But it will work only for rows being added to your DataTable after adding this column.
If you adding this identity column to the DataTable with existed rows - this will not update existed rows, so in this case you're still need loop over your existed rows and update them manually.

Linq SELECT query not returning first row of DataTable

This should be a real simple operation but for some reason it's not working as expected. I'm trying to copy all the rows out of a DataTable "mainDatatable" that have their Export Cell = 'True'
Here's my code:
DataTable table = model.getData.Tables["mainDataTable"].Clone();
var rows = model.getData.Tables["mainDatatable"].Select("Export = 'True'");
foreach (var row in rows)
{
table.ImportRow(row);
}
Now, When i run this it always gets all rows with Export = "True", all but the very first row that is in the DataTable... Am i doing something wrong??
I cannot see any reason why you are not getting this if your table-data is all correct. Please check this:-
Is your True actually a string? If Yes, please check the data again. There might be a *space * with the 'true' in the first row.
I'm not that familiar with DataTable but in Linq an query isn't build with Select but with Where.
So I would try something like:
var rows = model.getData.Tables["mainDatatable"].AsEnumerable().Where(x=>x.Field<string>("Export").Equals("true"));
or - if its a boolean
var rows = model.getData.Tables["mainDatatable"].AsEnumerable().Where(x=>x.Field<bool>("Export"));

How to make column names the first row?

I have a query using dynamic pivot, so the column names change based on the data. My code generates a .csv file based on the result of the query. I don't know how I can make the header, as I cannot hard-code column names. Is it possible somehow to make the header of the query result the first row of the recordset?
Thanks.
ADDED: Just realized that I don't even know how to fetch the data in my C# code if I don't know what columns I have... So that I cannot do something like this:
result.AddRange(from DataRow dr in dt.Rows
select new DailyTransactionSheet
{
Serve = Convert.ToInt32(dr["Serve"]),
Remits = Convert.ToInt32(dr["Remits"]),
List = Convert.ToInt32(dr["List"]),
Billing = Convert.ToInt32(dr["Billing"]),
DollarSent = Convert.ToInt32(dr["DollarSent"]),
FileAck = Convert.ToInt32(dr["FileAck"]),
});
}
as per comments:
basically you need to execute query and fetch information about columns form it, depending on how your're executing it, there can be several options:
SQLDataReader to fetch results, you can get column information from GetSchemaTable.Columns GetSchemaTable
or
SqlDataAdapter.Fill(DataSet) DataSet.Tables[0].Columns - these methods and properties you should read about DataSet.Tables
here is example from msdn:
private void PrintRows(DataSet dataSet)
{
// For each table in the DataSet, print the row values.
foreach(DataTable table in dataSet.Tables)
{
foreach(DataRow row in table.Rows)
{
foreach (DataColumn column in table.Columns)
{
Console.WriteLine(row[column]);
}
}
}
}

error add a datatable row to another datatable

I have datatable1 which has 11 columns and 100,000 rows.. I would like to do a check to see if the text in column one starts with "one" and if it does, add that row into the second datatable. I have done the below but yet still it does not work.. I get the error that the row belong to another table
foreach (DataRow r in queryDataTable.Rows)
{
if (r[0].ToString().StartsWith(queryString))
{
dt.ImportRow(r);
}
}
You cannot directly import the row of one table into another datatable. You need to create a new row and then copy the row.
Try this -
dt.Rows.Add(r.ItemArray)
Instead of your for loop, you may use LINQ to select those rows which StartsWith queryString and then you can use CopytoDataTable method to create a new table for the selected rows.
var NewTable = queryDataTable.AsEnumerable()
.Where(r => r.Field<string>(0).StartsWith(queryString))
.CopyToDataTable();
Remember to include using System.Linq; at the top.

Enumerate over DataTable, filter items, then revert to DataTable

I'd like to filter items in my DataTable by whether a column value is contained inside a string array by converting it to an IEnumerable<DataRow>, afterwards I'd like to re-convert it to DataTable since that's what my method has to return.
Here's my code so far:
string[] ids = /*Gets string array of IDs here*/
DataTable dt = /*Databasecall returning a DataTable here*/
IEnumerable<DataRow> ie = dt.AsEnumerable();
ie = ie.Where<DataRow>(row => ids.Contains(row["id"].ToString()));
/*At this point I've filtered out the entries I don't want, now how do I convert this back to a DataTable? The following does NOT work.*/
ie.CopyToDataTable(dt, System.Data.LoadOption.PreserveChanges);
return dt;
I would create an empty clone of the data table:
DataTable newTable = dt.Clone();
Then import the rows from the old table that match the filter:
foreach(DataRow row in ie)
{
newTable.ImportRow(row);
}
Assuming that you want to filter the rows in-place, that is the filtered rows should be returned in the same DataTable that was created through the original database query, you should first clear the DataTable.Rows collection. Then you should copy the filtered rows to an array and add them sequentially:
ie = ie.Where<DataRow>(row => ids.Contains(row["id"].ToString())).ToArray();
dt.Rows.Clear();
foreach (var row in ie)
{
dt.Rows.Add(row);
}
An alternative way to achieve this could be to simply iterate through the rows in the DataTable once and delete the ones that should be filtered out:
foreach (var row in dt.Rows)
{
if (ids.Contains(row["id"].ToString()) == false)
{
row.Delete();
}
}
dt.AcceptChanges();
Note that if the DataTable is part of a DataSet that is being used to update the database, all modifications made to the DataTable.Rows collection will be reflected in the corresponding database table during an update.

Categories

Resources