Problem with DataTable.Select - c#

Is there a way to find a value in DataTable use method Select:
items.Select("Number like '%10%'");
But Number type is Int, and this code doesn`t work...

Look at the T-SQL CAST and CONVERT functions, they might help you here. Basically, in your query, use either CAST or CONVERT (not sure which is best suited for you) to change the int into a string that you can perform a LIKE on.

For those reading in the future, this might help:
DataRow[] matchingRows = a.Select("Convert(Age, 'System.String') like '2%' "); // cut and paste from my code
So in your code it would be:
DataRow[] matchingRows = a.Select("Convert(Number, 'System.String') like '10%' "); // where Number is the name of your column.

If you really want to have such behaviour, then it would be better just add to your table additional computed column like "NumberText" with type String, which will store the same values as for column Number. Then you can execute your expression: items.Select("NumberText like '%10%'");

You can use linq the following way:
var matchingRows =
from item in items.AsEnumerable()
where item.Field<string>("Number").Contains("10")
select item;
or if Number is actually a number:
var matchingRows =
from item in items.AsEnumerable()
where item.Field<double>("Number").ToString().Contains("10")
select item;

If memory serves you need to escape a single quote by doubling it. Ie:
items.Select("Number like ''%10%''");

You can use DataView to filter values in DataTable
DataView dv = new DataView(dtSample);
dv.RowFilter = "Number like '%10%'";

Related

Unable to have a dash (-) in the name of a datatable column for filtering

I got a problem with filtering datatables. One Column is calles BANF-Nummer. Using a filter, I got a error message. I wrote the following code for that:
FilterExpression = "(Kontierungsobjekt = 'Kostenstelle' OR Kontierungsobjekt = 'Co-Auftrag') AND BANF-Nummer > '-1'";
dv.RowFilter = FilterExpression; //ERROR!
The error message is:
Cannot find column [Nummer]
There is another post with a similar problem linked below:
Unable to Have (-) Dash in DataView Filter C#
This fix doesn't solve my problem. If I try this:
FilterExpression = "(Kontierungsobjekt = 'Kostenstelle' OR Kontierungsobjekt = 'Co-Auftrag') AND [BANF-Nummer] > '-1'";
dv.RowFilter = FilterExpression; //ERROR!
The error message is then:
Cannot find column [BANF-Nummer]
If I test this function with another column, for example Kostenstelle, it works perfectly. So the error is definitive in the name BANF-Nummer, I cannot change.
Here a screenshot of my problem:
enter image description here
Would be grateful for every advice.
You have to wrap them in squared brackets:
FilterExpression = "(Kontierungsobjekt = 'Kostenstelle' OR Kontierungsobjekt = 'Co-Auftrag') AND [BANF-Nummer] > '-1'";
Thats mentioned in the documentation here
Since you have tried it but it still didn't work:
What does dv.Table.Columns.Contains("BANF-Nummer") return? I suspect false.
You're right Tim, it returns false
Then the table doesn't contain this column, maybe the sql-query that was used to fill this table used an alias or you have a typo.
Use following LINQ query to find your column(your table contains 104 columns as commented):
List<DataColumn> candidates = dv.Table.Columns.Cast<DataColumn>()
.Where(c=> c.Colum‌​nName.StartsWith("BA‌​NF", StringComparison.OrdinalIgnoreCase))
.ToList();
Ok, I figured out, that internal the name in sharepoint is stored in unicode.
https://social.msdn.microsoft.com/Forums/sharepoint/en-US/ea47e82b-273e-48bc-a6cb-c961e2c7c06a/how-to-set-and-get-item-if-the-sharepoint-column-name-has-space?forum=sharepointdevelopmentprevious
And I can convert it like this:
string Key = Field.Key; //Co_x002D_Auftrag
Key = System.Xml.XmlConvert.DecodeName(Key); //Co-Auftrag
Key = System.Xml.XmlConvert.EncodeName(System.Xml.XmlConvert.DecodeName(Key)); //Co_x002D_Auftrag
Now I have to figure out, if - and how - I can use that for my filtering function.

using getdate() in filter expression of DataSet.Select() method

I would like to know the possibility of using SQL functions (in this case getdate()) in filter expressions, like the one stated below:
DataTable dataTable = new DataTable();
dataTable.Columns.Add("MyDate", typeof(DateTime));
dataTable.Columns.Add("MyString", typeof(string));
var row = dataTable.NewRow();
row[0] = DateTime.Now.AddDays(1);
row[1] = "XXX";
dataTable.Rows.Add(row);
//Evaluation
//Example 1 - IT WORKS
//var rows = dataTable.Select("([MyString] = 'XXX') And [MyDate] > #2012/03/03#");
//Example 2 - IT DOESN'T WORK
var rows = dataTable.Select("([MyString] = 'XXX') And [MyDate] >= (GETDATE())");
Does anyone know if it's possible?
For some reasons I can't change the original code that just evaluate a string, and I need to fetch the current date and add more 2 days on that. something like DATEADD(day,2,[MyDate])
I know that one way would be changing the source code and create a literal string with date, like example 2.
Any help is appreciated. Thanks!
You could concatenate DateTime.Now into your filter:
var filter = string.Format("[MyString] = 'XXX' And [MyDate] >= #{0:yyyy-MM-dd}#", DateTime.Now);
var rows = dataTable.Select(filter);
If it needs to be more than two days after, then you could change DateTime.Now, to DateTime.Now.AddDays(2).Date
You can look at this link to check if something like that is supported :
http://www.csharp-examples.net/dataview-rowfilter/
I did a quick check and date functions don't seem to be supported.
How did I come across that link ? I just googled for the api you are using and came to this link first :
https://msdn.microsoft.com/en-us/library/system.data.datatable.select%28v=vs.110%29.aspx
clicked on the select version with one string and came to
https://msdn.microsoft.com/en-us/library/det4aw50(v=vs.110).aspx
I then started to read.
I am passing all this information because I think looking through what is already available on the internet and knowing what to look for and how is just as important as programming itself.
What you can do in your situation of course is to use DateTime.today to get to the current date, and create a select string that makes use of that result. Don't put DateTime.today as string in your select, that won't work either.

How to RowFilter a column with a period in the name?

I have a DataTable pupulated from a cube with the column names declared as:
[Measures].[Stock Qty]
The DataTable fills correctly, however when trying to apply a RowFilter using:
"[Measures].[Stock Qty] >= 2000"
I get the following error:
"[Measures.StockQty] not found
I also tried using just the column name:
"[Stock Qty] >= 2000"
but this also fails with a not found error.
Is it at all possible to filter a DataTable using column names that contain periods, if so how?
You can rename the datatable columns (for replacing period with "_") & they try rowfilter.
Eg.:
dataTable.Columns["Stock Qty"].ColumnName =
dataTable.Columns["Stock Qty"].ColumnName.Replace(" ", "_");
Why do you want to use the RowFilter at all? If you're using .NET 3.5 or higher i would recommend to use Linq-To-DataTable instead which is more powerful and readable:
IEnumerable<DataRow> filteredRows = tblMeasures.AsEnumerable()
.Where(r => r.Field<int>("Stock Qty") >= 2000);
if you need a DataTable again:
DataTable tblFiltered = filteredRows.CopyToDataTable();
By the way, if the name of column in the DataTable is "Stock Qty" your last approach should work since you need to wrap it in brackets.
tblMeasures.DefaultView.RowFilter = "[Stock Qty] >= 2000";
So you should use the debugger to see the real name and type of the column.

Get sum from a DataColumn values in C#

I have a table in a dataadapter. I want to get the count and sum of a specific column of it. How is that possible?
This is the code for reach to the column, what after that?
DataColumn buy_count = myDataSet.Tables["all_saled"].Columns["how_much_buy"]
I know that we have sum, count,... in SQL, but how can I do it in C#?
You can use LINQ to DataSets
var sales = myDataSet.Tables["all_saled"].AsEnumerable();
var buy_total = sales.Sum(datarow => datarow.Field<int>("how_much_buy"));
Check the LINQ to DataSets 101 Samples
P.S. might need the System.Data.DataSetExtensions assembly referenced.
Use the DataTable.Compute method:
int total = (int)myDataSet.Tables["all_saled"].Compute("SUM(how_much_buy)", null);

Sorting DataTable string column, but with null/empty at the bottom

I need to sort a DataTable or DataGridView by a column that is a string value, but with null/empty values at the BOTTOM when sorting ASCENDING.
The DataTable is NOT populated by a SQL statement, so no order by.
If I do
DataGridView1.Sort(New RowComparer(System.ComponentModel.ListSortDirection.Ascending))
then it throws an exception, saying that the DataGridView is DataBound, which is correct, but doesn't help me, and I want to keep it databound.
It's .NET 2.0, which means no LINQ available!
in some cases you could do this if you have another extra column in your table:
SELECT completed, completed IS NULL AS isnull
FROM TABLE
ORDER BY isnull DESC, completed DESC
Edit:
Like this in VB.NET
For Each srSearchResult In srcSearchResultCollection
Try
dr = dt.NewRow()
dr("cn") = srSearchResult.GetDirectoryEntry().Properties("cn").Value
dr("Account") = srSearchResult.GetDirectoryEntry().Properties("sAMAccountName").Value
dr("Nachname") = srSearchResult.GetDirectoryEntry().Properties("sn").Value
dr("Vorname") = srSearchResult.GetDirectoryEntry().Properties("givenname").Value
dr("Mail") = srSearchResult.GetDirectoryEntry().Properties("mail").Value
dr("HomeDirectory") = srSearchResult.GetDirectoryEntry().Properties("homedirectory").Value
dr("LogonScript") = srSearchResult.GetDirectoryEntry().Properties("scriptPath").Value
dr("IsNull") = String.IsNullOrEmpty(dr("Nachname").ToString())
dt.Rows.Add(dr)
Catch ex As Exception
End Try
Next srSearchResult
dt.DefaultView.Sort = "IsNull ASC, Nachname ASC"
Davide Piras has a good solution, however there is another simplest solution I have
Add a new column and do it in just one line
// just, add a new column
ActualDataTable.Columns.Add("NullEmptyCheck", typeof(int), "ColumnNameToSort is Null OR ColumnNameToSort = ''");
// apply sort expression
ActualDataTable.DefaultView.Sort = "NullEmptyCheck asc, ColumnNameToSort asc";
// pass datasource to grid
MyGridView.DataSource = ActualDataTable.DefaultView;
MyGridView.DataBind();
even if the DataTable you bind to the user interface control DataGridView is not populated via SQL, you can still sort it using a DataView, you can do something like this:
DataView myView = myDataTable.DefaultView;
myView,Sort = "yourColumnName ASC";
then you do your binding.
how does it work? Are the null values in the top or in the bottom?
For those who are looking for a way to achieve this in .NET 4+, here is a example :
DataTable orderedDataTable = sourceDataTable.AsEnumerable()
.OrderByDescending(row => !string.IsNullOrWhiteSpace(row.Field<string>("COLUMN_NAME")))
.ThenBy(row => row.Field<string>("COLUMN_NAME"))
.CopyToDataTable();
This will place null values at the end of the table (note that both empty and white spaces strings will have the same rank) and then order the requested column in ascending order.

Categories

Resources