I have a DataTable named 'dtStocksCriteria'; each cell in it should turn into a process function. So I should traverse all rows and columns.
For this purpose I have Parallel loop on rows. Then I select the Row with this Code:
DataView dv = new DataView(dtStocksCriteria);
dv.RowFilter = "xStockCode_FK = " + stock.Code;
After that in an Inner Parallel loop I should retrieve each column value with something like this code.
val = (double)dv[0]["column name"];
This Assignment take about 0.5 seconds which is too long for me. I want to reduce that to approximately 1 millisecond.
I have 398 rows and 110 columns in mt data table, in case that helps.
Does anyone have any ideas?
In C# working with DataView or DataRow or DataTable takes time.
BUT
If you use DataRow[int index] to retrive a cell value it should takes less time than using DataRow[string ColumnName] .
SO
When I use 'index' instead of 'ColumnName' it makes my code faster.
BUT
It is still slow because I have too much columns. So the best solution is to reduce the columns count first.
Related
I need to compare two datatable and simply check if Datatable(A) contains rows which are in Datatable(B).
Then rows from (B) which will not be in (A) will be inserted into (A). So basically target is to insert rows from (B) into (A) but only those rows which are not already presented.
Both Datables have same structure, same columns and datatypes.
I donĀ“t want to do it with foreach loop for every Datarow(B) and compare with every Datarow in (A) it will be very slow solutions.
Thank you in advance
I have a datatable with almost 20 columns in it. in another DT i get only the columns I want. Recently my requirements have changed i.e. Firstly the number of columns in the original DT were constant but now it increases or decreases depending upon the data.
So now, if I statically provide the column names I need in my new DT it isnt of much use to me.
Is there any way in which I can include those columns which may or may not be in the Original Datatable????
For eg: col1|col2|col3|.......col20.
The columns that may bve present or absent fall between col12 and col 16. Is there anyway in which I could make it work????
EDIT:
I want col1,col2,col3 and all columns aftr col12...can I do it???
You can have total number of columns from datatable using
DataTable.Columns.Count
So you will know how many columns are there and you will know which column is in datatable and which is not.
I have a datatable in C# with a "price" column and an "allocation" column, and I need to multiply the price column by the allocation column and put the result in the price column. Is there a way to do with without looping over the table? I have tried something like this:
DataTable dt = getData();
dt.Columns["Price"].Expression = "Allocation * Price";
But obviously this gives me the following exception:
Cannot set Expression property due to circular reference in the expression.
Does anyone know of another way to accomplish this? Thanks beforehand.
You could use a LINQ expression to do it in one line:
dt.Rows.ForEach(x => x["Price"] = (double)x["Price"] * (double)x["Allocation"]);
You could just add another column to the DataTable:
dt.Columns.Add("TotalPrice", typeof(decimal));
dt["TotalPrice"] = "Allocation * Price";
Add a new column whose value is calculated from the other two:
dt.Columns.Add("TotalPrice", typeof(decimal), "Allocation * Price");
With this approach, the TotalPrice will always be up to date if you change the Price or Allocation
If you don't have a seperate column, what happens when something makes the calculation execute again....
At some point the amount of code you have to add bend datatable to do what you want (without introducing a mass of potential 'erm features) will be more effort than just knocking up a class to hold the stuff.
Read from datatable write from databale isn't hard, nor is binding to a list of thingies.
I have a problem with my asp.net program. I am doing a Datatable.Compute on a very large database with a like condition in it. The result takes something like 4 minutes to show or does a Request timeout. If I do the same request with a = and a fix text, it takes nearly 1 minute to show, which for my use is acceptable.
Here is the line that is so slow:
float test = (int)Datatbl.Tables["test"].Compute("COUNT(pn)", "pn like '9800%' and mois=" + i + " and annee=" + j);
I have been searching for a solution for 2 days.
Please help me.
Are you retrieving the data in your Datatable from a database? Do you have access to the database?
If so, one option is to research methods of moving this lookup and aggregation into the database instead of doing it in your C# code. Once it is in the database, if required, you could add indexes for the 'mois' and 'annee' columns which may speed up the look up considerably. If '9800' is a hardcoded value, then you could even add a denormalisation consisting of a boolean column indicating whether the 'pn' column begins with '9800' and put an index on this column. This may make the lookup very fast indeed.
There are lots of options available.
I found it.
I use the Dataview and send the result to a DataTable. This sped up the process 10 times
Here is an exemple:
DataView dv = new DataView(Datatbl.Tables["test"], filter, "pn", DataViewRowState.CurrentRows);
DataTable test = dv.ToTable();
and then you can use the "test" DataTable.
I am writing this in C# using .NET 3.5. I have a System.Data.DataSet object with a single DataTable that uses the following schema:
Id : uint
AddressA: string
AddressB: string
Bytes : uint
When I run my application, let's say the DataTable gets filled with the following:
1 192.168.0.1 192.168.0.10 300
2 192.168.0.1 192.168.0.20 400
3 192.168.0.1 192.168.0.30 300
4 10.152.0.13 167.10.2.187 80
I'd like to be able to query this DataTable where AddressA is unique and the Bytes column is summed together (I'm not sure I'm saying that correctly). In essence, I'd like to get the following result:
1 192.168.0.1 1000
2 10.152.0.13 80
I ultimately want this result in a DataTable that can be bound to a DataGrid, and I need to update/regenerate this result every 5 seconds or so.
How do I do this? DataTable.Select() method? If so, what does the query look like? Is there an alternate/better way to achieve my goal?
EDIT: I do not have a database. I'm simply using an in-memory DataSet to store the data, so a pure SQL solution won't work here. I'm trying to figure out how to do it within the DataSet itself.
For readability (and because I love it) I would try to use LINQ:
var aggregatedAddresses = from DataRow row in dt.Rows
group row by row["AddressA"] into g
select new {
Address = g.Key,
Byte = g.Sum(row => (uint)row["Bytes"])
};
int i = 1;
foreach(var row in aggregatedAddresses)
{
result.Rows.Add(i++, row.Address, row.Byte);
}
If a performace issue is discovered with the LINQ solution I would go with a manual solution summing up the rows in a loop over the original table and inserting them into the result table.
You can also bind the aggregatedAddresses directly to the grid instead of putting it into a DataTable.
most efficient solution would be to do the sum in SQL directly
select AddressA, SUM(bytes) from ... group by AddressA
I agree with Steven as well that doing this on the server side is the best option. If you are using .NET 3.5 though, you don't have to go through what Rune suggests. Rather, use the extension methods for datasets to help query and sum the values.
Then, you can map it easily to an anonymous type which you can set as the data source for your grid (assuming you don't allow edits to this, which I don't see how you can, since you are aggregating the data).
I agree with Steven that the best way to do this is to do it in the database. But if that isn't an option you can try the following:
Make a new datatable and add the columns you need manually using DataTable.Columns.Add(name, datatype)
Step through the first datatables Rows collection and for each row create a new row in your new datatable using DataTable.NewRow()
Copy the values of the columns found in the first table into the new row
Find the matching row in the other data table using Select() and copy out the final value into the new data row
Add the row to your new data table using DataTable.Rows.Add(newRow)
This will give you a new data table containing the combined data from the two tables. It won't be very fast, but unless you have huge amounts of data it will probably be fast enough. But try to avoid doing a LIKE-query in the Select, for that one is slow.
One possible optimization would be possible if both tables contains rows with identical primary keys. You could then sort both tables and step through them fetching both data rows using their array index. This would rid you of the Select call.