Update multiple rows in datatable without loop - c#

I have two datatable with conditions in application and want some processing for multiple rows to update column value.
For example:
I have datatable1 with 10000 rows. I want to filter rows by datatable.select("condition") and as per condition, I want to update row values.
If for any condition, I found 20 rows from datatable. I want to update those 20 records in one shot. Not in any loop. I have datarow array for those values to update in datable.

You can try out the following linq,
DataTable recTable = new DataTable();
// do stuff to populate table
recTable.Select(string.Format("[code] = '{0}'", someName)).ToList<DataRow>().ForEach(r => r["Color"] = colorValue);
You can substitute your columns and values here...

To Update Row With Multiple Condition use This
datatable.Select(string.Format("[lineNo]='{0}' and [Position]>='{1}' ", lineNo, Position)).ToList<DataRow>().ForEach(r => r["Linetext"] ="Sample Text" );

If you want to default a column value with abc use Expression, then you could use the below code.
dt.Columns.Add("ColumnName").Expression = "'abc'";
In case if you need to pass the value dynamically using a variable, you could use the below code.
string str = "abc";
dt.Columns.Add("ColumnName").Expression = "'" + str + "'";

Related

How to select from a datatable where the column is part of a string in C#.net

I have a datatable that I am trying to make an update on.
my datatable is the data source of a data gridview (Forms application)
I want to update all rows that are part of a textbox
the textbox contains a comma separated values such as
A1,A11,B4,B38,C44
I have this code but stuck on how to make it working
DataTable dt = new DataTable();
dt = (DataTable)grd1.DataSource;
DataRow[] dr = dt.Select("'," + TextBox1.Text + ",' LIKE '%,Code,%'");
foreach (DataRow row in dr)
{
row["Price"] = 1000;
}
The problem is in this code
"'," + TextBox1.Text + ",' LIKE '%,Code,%'"
it does not retuen any rows so I think I did not write it the right way.
How to fix my select line?
Note : I added a comma before and after so I do not get "T37" when I am looking for "T3"
Your question wasn't easy to understand for me, but you seem to be saying that you will type a list of values into the textbox and these values are to be looked up in the [Code] column of the datatable. I'm not clear on whether the Code column itself is a single value or a comma separated list of codes, so I'll answer for both. Assuming the Code column is a CSV, and you want that any row where any one of the values in Code is one of these values in the textbox, shall have its price updated to 1000:
So for a textbox of "A1,B1" and a datarows like:
Code Price
A1,C3 200
B4,C7 400
The 200 row shall be updated and the 490 row shall not
I'd use LINQ for this rather than datatable select
var codes = textbox.Split(',');
var rows = dt.AsEnumerable().Where(r => codes.Any(c => (r["Code"] as string).Split(',').Contains(c)));
foreach(var r in rows)
r["Price") = 1000;
If you're doing this a lot I wouldn't have the codes in the row as a CSV string; a row field is allowed to be an array of strings - storing the codes as an array in the row will save having to split them every time you want to query them
If I've got this wrong and the row contains just a single Code value, the logic is the same, it just doesn't need the split(though the code above would work, it's not optimal):
var rows = dt.AsEnumerable().Where(r => codes.Any(c => (r["Code"] as string) == c));
And actually if you're going to be doing this a lot, I would index the datatable:
//if it's a csv in the datatable
var index = dt.AsEnumerable()
.SelectMany(r => r["Code"].ToString().Split(','), (row, code) => new { R=row, C=code})
.ToLookup(o => o.C, o => o.R);
This will give something like a dictionary where a code maps to a list of rows where the code appears. For a row set like
Code Price
A1,C3 200
B4,C3 400
You get a "dictionary" like:
A1: { "A1,C3", 200 }
C3: { "A1,C3", 200 },{ "B4,C3", 400 }
B4: { "B4,C3", 400 }
so you could:
foreach(var c in codesTextbox.Split)
foreach(var row in index["c"])
row["Price"] = 1000;
If the Code column doesn't contain a csv, doing a selectmany should still be fine, but to optimize it:
var index = dt.AsEnumerable().ToLookup(r => (string)r["Code"]);

select query with contain condition in datatable using c#

I have a datatable and i need to put CONTAINS condition in it.Now am retrieving datatable rows using below query
DataRow[] resultss = dtDocument.Select("DocumentElementText='" + columnValue + "'");
but i need to put condition like contains in this query for retrieving values from datatable.
above is my datatable. this query dtDocument.Select("DocumentElementText='New Package'"); will return me the first row from the datatable.What i need is , i need to retrieve the row which contains <td>NAME</td> from this datatable. How to retrieve the row ..??
Regards
Arshad
try this
DataRow[] resultss = dt.AsEnumerable().Where(row => row.Field<string>("DocumentElementText").Contains("Enter Your String Here")).Select(row => row).ToArray<DataRow>();

how to get a value from a filtered values of dataview in C#?

I have a filtered data view, from which I have to extract the values. Problem is that when I do this, I am getting the values from non filtered data also.
dv1.RowFilter = "collegeno=" +i;
for(int k=1;k<dv1.count;k++)
{
//inserting data in database; there is column in database table; I am inserting into it;
dv1.Table.Rows[k]["roomno"]);
}
For ex: The total no. of rows in DataView is 200;
When i=1 I have 30 records;
If I supply k=4, then I should get fourth row from this 30 records.
But I am getting 4th row of the 200 records..
The code you have written is accessing the main table using the code block dv1.Table.
Instead try as this
dv1[k]["roomno"]
This code works on DataView, on which the filter is applicable.
If you use DataView.Table then it will access the non-filtered results.
Reference Link: MSDN - DataView.RowFilter
If I supply k=4, then I should get fourth row from this 30 records.
But I am getting 4th row of the 200 records..
That's because you're querying the table, not the view. Instead you should do this:
dv1.RowFilter = "collegeno=" +i;
object value = dv1[k]["roomno"];
Depending on what you need, you might want to use the DataTable.Select method instead of a DataView:
var rows = table.Select("collegeno=" +i);
object value = rows[k]["roomno"];
DataTable dt = dv.ToTable();
for(int k=1;k<dt.Rows.Count;k++)
{
dt.Rows[k]["roomno"];
//dv1.Table.Rows[k]["roomno"]);
}

Selecting second set of 20 row from DataTable

I have a DataTable I am populating from SQL table with the following example columns
ID
Type
Value
I am populating the DataTable with rows which are of a certain type. I want to select the rows 10 - 20 from my resulting DataTable:
Connect conn = new Connect();
SqlDataAdapter da = new SqlDataAdapter(SQL, conn.Connection());
//Creates data
DataTable d = new DataTable();
da.Fill(d);
DataRow[] result = d.Select();
In the above code I have omitted the main SQL, and currently I have no select for my DataRow array. I cannot find a way to reference the row numbers.
So for instance I am looking for something like Select("rownum > X && rownum < Y")
I have searched here, and a number of other resources to no avail. Any clues would be really handy, or just a simple not possible.
It's always better to select only what you need from the database(f.e. by using the TOP clause or a window function like ROW_NUMBER) instead of filtering it in memory.
However, you can use Linq-To-DataSet and Enumerable.Skip + Enumerable.Take:
var rows = d.AsEnumerable()
.Skip(9).Take(11); // select rows 10-20 as desired (so you want 11 rows)
If you want a new DataTable from the filtered result use CopyToDataTable, if you want a DataRow[] use rows.ToArray().
I would just do the 'take' and 'skip' command and keep it simple:
d.Select().Skip(10).Take(10); // skips 10 rows, then selects ten after that.
This would be assuming you have the Linq using set (using System.Linq)

how to convert the entire content of a DataTable column to a delimited string in C#?

I am retrieving data from an MSSQL server using the SqlDataAdapter and DataSet. From that DataSet I am creating a DataTable. My goal is to convert each column of the table into a string where the elements are comma delimited. I figured that I would try the string conversion first before making the delimiter work.
The code runs in the code-behind of an ASP.Net page. The ultimate goal is to pass the string to a jscript variable, it's a "functional requirement" that I create a delimited string from the columns and that it has to end up as a jscript variable.
Here's what I have thus far:
DataSet myDataSet = new DataSet();
mySqlDataAdapter.Fill(myDataSet);
DataTable temperature = myDataSet.Tables["Table"];
// LOOP1
foreach (DataRow row in temperature.Rows)
// this loop works fine and outputs all elements
// of the table to the web page, this is just to
// test things out
{
foreach (DataColumn col in temperature.Columns)
{
Response.Write(row[col] + " ### ");
}
Response.Write("<br>");
}
// LOOP2
foreach (DataColumn column in temperature.Columns)
// this loop was meant to take all elements for each
// column and create a string, then output that string
{
Response.Write(column.ToString() + "<br>");
}
In LOOP1 things work fine. My data has 4 columns, all are appropriately rendered with one record per row on the web page.
I saw the code for LOOP2 at http://msdn.microsoft.com/en-us/library/system.data.datacolumn.tostring.aspx which seems to do exactly what I need except it does not actually do what I want.
The only thing LOOP2 does is write 4 lines to the web page. Each line has the header of the respective table column but none of the additional data. Clearly there's either a logic flaw on my part or I misunderstand how DataColumn and .toString for it works. Please help me out on this one. Thanks in advance.
EDIT:
Here's an SQL query result example, this is what the Table looks like:
Table quesry result # ImageShack
What I want to end up are four strings, here's an example for the string that would be created from the second column: "-6.7, -7, -7.2, -7.3, -7.3".
This code will concatenate values from cells under each column with ", ":
foreach (var column in temperature.Columns)
{
DataColumn dc = column as DataColumn;
string s = string.Join(", ", temperature.Rows.OfType<DataRow>()
.Select(r => r[dc]));
// do whatever you need with s now
}
For example, for DataTable defined as:
DataTable table = new DataTable();
table.Columns.Add(new DataColumn("Column #1"));
table.Columns.Add(new DataColumn("Column #2"));
table.Rows.Add(1, 2);
table.Rows.Add(11, 22);
table.Rows.Add(111, 222);
... it will produce "1, 11, 111" and "2, 22, 222" strings.
Edit: I saw you chose to declare column as var as opposed to DataColumn, is that a matter of personal preference/style or is there an issue with coding?
Consider following scenario (on the same data table example as above):
// we decide we'll use results later, storing them temporarily here
List<IEnumerable<string>> columnsValues = new List<IEnumerable<string>>();
foreach (DataColumn column in temperature.Columns)
{
var values = temperature.Rows.OfType<DataRow>()
.Select(r => r[column].ToString())
columnsValues.Add(values);
}
We assume we now got list of list of column values. So, when we print them, like this:
foreach (var lisOfValues in columnsValues)
{
foreach (var value in listOfValues)
{
Debug.Write(value + " ");
}
Debug.WriteLine("");
}
We expect to see 1 11 111 followed by 2 22 222. Right?
Wrong.
This code will output 2 22 222 twice. Why? Our .Select(r => r[column].ToString()) captures column variable - not its value, but variable itself - and since we don't use it immediately, once we're out of loop all we know is last value of column.
To learn more about this concept search for closures and captured variables - for example, in posts like this.
Summary:
In this very case you can go with DataColumn in foreach statement. It doesn't matter here because we're enumerating through our .Select(r => r[dc]) either way inside the loop (precisely, string.Join does that for us), producing results before we get to next iteration - whatever we capture, is used immediately.
The link you have posted clearly states
The Expression value, if the property
is set; otherwise, the ColumnName
property.
and that is what is happening. You get column names.
This could help: How to convert a DataTable to a string in C#?

Categories