Verifying that a DataTable is sorted
I am working on creating a custom database test condition in Visual Studio, and I am trying to verify a sort order.
I have no problem verifying that the rows in a DataTable are actually sorted, but I also want to verify that each sort column has at least one grouping with more than one distinct value.
I am maintaining a list of integers that define the sorted columns (negative integers indicate a descending sort order - and the absolute value of the integer is the column number).
Let me clarify.
I am writing a unit test condition that verifies a sorted DataTable. I can verify that the row are in the correct sorted order, but I want to verify that the result set contains data that actually tests the sort. In order words, a result set with only one row or any number of duplicate rows is indeed sorted, but that doesn't actually test the sort.
I need to verify that each level of the sort contains at least two distinct values in at leas开发者_StackOverflow中文版t one grouping.
In the past I used a combination of SQL and .Net code and used the following set of queries to make sure there was enough data to test the sort.
SELECT TOP 1 COUNT(DISTINCT column1)
FROM table
HAVING COUNT(DISTINCT column1) > 1
SELECT TOP 1 column1, COUNT(DISTINCT column2)
FROM table
GROUP BY column1
HAVING COUNT(DISTINCT column2) > 1
SELECT TOP 1 column1, column2, COUNT(DISTINCT column3)
FROM table
GROUP BY column1, column2
HAVING COUNT(DISTINCT column3) > 1
Where I have a query for each level and all queries must return a non-empty result set in order for the unit test to pass.
My real question is how do I duplicate/convert the SQL code above to LINQ?
I presume you verify that it's sorted with a double loop along the lines of
for (int i = 1; i < rowCount; i++) { for (int j = 0; j < sortColCount; j++) { int col = colNum(sortCols[j]); int d = Compare(GetValue(rows[i], col), GetValue(rows[i-1], col)); if (d == 0) continue; // Insert here Assert(d == colDir(sortCols[j])); } }What you need to do is where I've put the comment insert a command to flag sort column d as tested (using e.g. a bool array). Then after the loop assert that each sort column is tested.
You could save the cost of the necessary iteration by hooking the DataTable's TableNewRow, RowChanging and RowChanged events to track/enforce whether or not the DataTable is sequenced the way you expect to be.
Otherwise, it's brute force:
foreach ( int i = 1 ; i < dt.Rows.Length ; ++i )
{
DataRow prev = dt.Rows[i-1] ;
DataRow curr = dt.Rows[i ] ;
Assert( CompareRows(prev,curr) <= 0 ) ;
}
Where CompareRows(prev,curr)
returns the usual sort of comparison result: -1 for prev < curr, 0 for prev == curr and +1 for prev > curr );
精彩评论