+2008-05-13 Atsushi Enomoto <atsushi@ximian.com>
+
+ * DataTableExtensions.cs, EnumerableRowCollection.cs,
+ EnumerableRowCollectionExtensions.cs, EnumerableRowCollection_1.cs,
+ OrderedEnumerableRowCollection.cs, TypedTableBase.cs,
+ TypedTableBaseExtensions.cs : lots of significant refactoring to
+ make collection/enumerable things unified.
+ Implemented OrderBy() and OrderByDescending().
+
2008-05-13 Marek Habersack <mhabersack@novell.com>
* DataRowComparer_1.cs: implemented GetHashCode and Equals.
//
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Linq;
public static EnumerableRowCollection<DataRow> AsEnumerable (this DataTable source)
{
- return new EnumerableRowCollection<DataRow> (source);
+ return new EnumerableRowCollection<DataRow> (new DataRowEnumerable<DataRow> (source));
}
[MonoTODO]
throw new NotImplementedException ();
}
}
+
+ class DataRowEnumerable<TRow> : IEnumerable<TRow>
+ {
+ DataTable source;
+
+ public DataRowEnumerable (DataTable source)
+ {
+ this.source = source;
+ }
+
+ public IEnumerator<TRow> GetEnumerator ()
+ {
+ foreach (TRow row in source.Rows)
+ yield return row;
+ }
+
+ IEnumerator IEnumerable.GetEnumerator ()
+ {
+ return GetEnumerator ();
+ }
+ }
}
using System;
using System.Collections;
+using System.Collections.Generic;
namespace System.Data
{
public abstract class EnumerableRowCollection : IEnumerable
{
+ internal static IEnumerable<TResult> Cast<TResult> (IEnumerable source)
+ {
+ foreach (object o in source)
+ yield return (TResult) o;
+ }
+
+ internal static IEnumerable<S> Select<TRow, S> (IEnumerable<TRow> source, Func<TRow, S> selector)
+ {
+ foreach (TRow row in source)
+ yield return selector (row);
+ }
+
+ internal static IEnumerable<TRow> Where<TRow> (IEnumerable<TRow> source, Func<TRow, bool> predicate)
+ {
+ foreach (TRow row in source)
+ if (predicate (row))
+ yield return row;
+ }
+
internal EnumerableRowCollection ()
{
}
{
public static class EnumerableRowCollectionExtensions
{
- [MonoTODO]
public static EnumerableRowCollection<TResult> Cast<TResult> (this EnumerableRowCollection source)
{
- throw new NotImplementedException ();
+ return new EnumerableRowCollection<TResult> (EnumerableRowCollection.Cast<TResult> (source));
}
- [MonoTODO]
public static OrderedEnumerableRowCollection<TRow> OrderBy<TRow, TKey> (this EnumerableRowCollection<TRow> source, Func<TRow, TKey> keySelector)
{
return OrderBy<TRow, TKey> (source, keySelector, Comparer<TKey>.Default);
}
- [MonoTODO]
public static OrderedEnumerableRowCollection<TRow> OrderBy<TRow, TKey> (this EnumerableRowCollection<TRow> source, Func<TRow, TKey> keySelector, IComparer<TKey> comparer)
{
- throw new NotImplementedException ();
+ return OrderedEnumerableRowCollection<TRow>.Create<TRow, TKey> (source, keySelector, comparer, false);
}
- [MonoTODO]
public static OrderedEnumerableRowCollection<TRow> OrderByDescending<TRow, TKey> (this EnumerableRowCollection<TRow> source, Func<TRow, TKey> keySelector)
{
return OrderByDescending<TRow, TKey> (source, keySelector, Comparer<TKey>.Default);
}
- [MonoTODO]
public static OrderedEnumerableRowCollection<TRow> OrderByDescending<TRow, TKey> (this EnumerableRowCollection<TRow> source, Func<TRow, TKey> keySelector, IComparer<TKey> comparer)
{
- throw new NotImplementedException ();
+ return OrderedEnumerableRowCollection<TRow>.Create<TRow, TKey> (source, keySelector, comparer, true);
}
public static EnumerableRowCollection<S> Select<TRow, S> (this EnumerableRowCollection<TRow> source, Func<TRow, S> selector)
{
- return new EnumerableRowCollection<S> (RunSelect<TRow, S> (source, selector));
- }
-
- static IEnumerable<S> RunSelect<TRow, S> (this EnumerableRowCollection<TRow> source, Func<TRow, S> selector)
- {
- foreach (TRow row in source)
- yield return selector (row);
+ return new EnumerableRowCollection<S> (EnumerableRowCollection.Select<TRow, S> (source, selector));
}
[MonoTODO]
public static EnumerableRowCollection<TRow> Where<TRow> (this EnumerableRowCollection<TRow> source, Func<TRow, bool> predicate)
{
- return new EnumerableRowCollection<TRow> (RunWhere<TRow> (source, predicate));
- }
-
- static IEnumerable<TRow> RunWhere<TRow> (EnumerableRowCollection<TRow> source, Func<TRow, bool> predicate)
- {
- foreach (TRow row in source)
- if (predicate (row))
- yield return row;
+ return new EnumerableRowCollection<TRow> (EnumerableRowCollection.Where<TRow> (source, predicate));
}
}
}
{
IEnumerable<TRow> source;
- internal EnumerableRowCollection (DataTable source)
- : this (new DataRowGenericCollection (source))
- {
- }
-
internal EnumerableRowCollection (IEnumerable<TRow> source)
{
this.source = source;
{
return GetEnumerator ();
}
-
- class DataRowGenericCollection : IEnumerable<TRow>
- {
- DataTable source;
-
- public DataRowGenericCollection (DataTable source)
- {
- this.source = source;
- }
-
- public IEnumerator<TRow> GetEnumerator ()
- {
- foreach (TRow row in source.Rows)
- yield return row;
- }
-
- IEnumerator IEnumerable.GetEnumerator ()
- {
- return GetEnumerator ();
- }
- }
}
}
//
using System;
+using System.Collections;
+using System.Collections.Generic;
namespace System.Data
{
public sealed class OrderedEnumerableRowCollection<TRow>
: EnumerableRowCollection<TRow>
{
- internal OrderedEnumerableRowCollection (DataTable source)
- : this (source)
+ internal static OrderedEnumerableRowCollection<TRow> Create<TRow, TKey> (IEnumerable<TRow> source, Func<TRow, TKey> keySelector, IComparer<TKey> comparer, bool descending)
{
+ return new OrderedEnumerableRowCollection<TRow> (new Sorter<TRow, TKey> (source, keySelector, comparer, descending));
+ }
+
+ OrderedEnumerableRowCollection (IEnumerable<TRow> source)
+ : base (source)
+ {
+ }
+ }
+
+ class Sorter<TRow, TKey> : IEnumerable<TRow>
+ {
+ IEnumerable<TRow> source;
+ Func<TRow, TKey> key_selector;
+ IComparer<TKey> comparer;
+ bool descending;
+
+ public Sorter (IEnumerable<TRow> source, Func<TRow, TKey> keySelector, IComparer<TKey> comparer, bool descending)
+ {
+ if (keySelector == null)
+ throw new ArgumentNullException ("keySelector");
+ if (comparer == null)
+ comparer = Comparer<TKey>.Default;
+ this.source = source;
+ this.key_selector = keySelector;
+ this.comparer = comparer;
+ this.descending = descending;
+ }
+
+ public IEnumerator<TRow> GetEnumerator ()
+ {
+ var list = new List<TRow> ();
+ foreach (TRow row in source)
+ list.Add (row);
+ list.Sort (delegate (TRow r1, TRow r2) {
+ return comparer.Compare (key_selector (r1), key_selector (r2));
+ });
+ if (descending)
+ for (int i = list.Count - 1; i >= 0; i--)
+ yield return list [i];
+ else
+ for (int i = 0, c = list.Count; i < c; i++)
+ yield return list [i];
+ }
+
+ IEnumerator IEnumerable.GetEnumerator ()
+ {
+ return GetEnumerator ();
}
}
}
throw new NotImplementedException ();
}
- [MonoTODO]
public EnumerableRowCollection<TResult> Cast<TResult> ()
{
- throw new NotImplementedException ();
+ return new EnumerableRowCollection<TResult> (EnumerableRowCollection.Cast<TResult> (this));
}
- [MonoTODO]
public IEnumerator<T> GetEnumerator ()
{
- throw new NotImplementedException ();
+ foreach (object o in Rows)
+ yield return (T) o;
}
- [MonoTODO]
IEnumerator IEnumerable.GetEnumerator ()
{
- return (IEnumerator) GetEnumerator ();
+ return GetEnumerator ();
}
}
}
public static class TypedTableBaseExtensions
{
- [MonoTODO]
public static EnumerableRowCollection<TRow> AsEnumerable<TRow> (this TypedTableBase<TRow> source) where TRow : DataRow
{
- throw new NotImplementedException ();
+ return new EnumerableRowCollection<TRow> (source);
}
public static OrderedEnumerableRowCollection<TRow> OrderBy<TRow, TKey> (this TypedTableBase<TRow> source, Func<TRow, TKey> keySelector)
return OrderBy<TRow, TKey> (source, keySelector, Comparer<TKey>.Default);
}
- [MonoTODO]
public static OrderedEnumerableRowCollection<TRow> OrderBy<TRow, TKey> (this TypedTableBase<TRow> source, Func<TRow, TKey> keySelector, IComparer<TKey> comparer)
where TRow : DataRow
{
- throw new NotImplementedException ();
+ return OrderedEnumerableRowCollection<TRow>.Create<TRow, TKey> (source, keySelector, comparer, false);
}
public static OrderedEnumerableRowCollection<TRow> OrderByDescending<TRow, TKey> (this TypedTableBase<TRow> source, Func<TRow, TKey> keySelector)
return OrderByDescending<TRow, TKey> (source, keySelector, Comparer<TKey>.Default);
}
- [MonoTODO]
public static OrderedEnumerableRowCollection<TRow> OrderByDescending<TRow, TKey> (this TypedTableBase<TRow> source, Func<TRow, TKey> keySelector, IComparer<TKey> comparer)
where TRow : DataRow
{
- throw new NotImplementedException ();
+ return OrderedEnumerableRowCollection<TRow>.Create<TRow, TKey> (source, keySelector, comparer, true);
}
- [MonoTODO]
public static EnumerableRowCollection<S> Select<TRow, S> (this TypedTableBase<TRow> source, Func<TRow, S> selector)
where TRow : DataRow
{
- throw new NotImplementedException ();
+ return new EnumerableRowCollection<S> (EnumerableRowCollection.Select<TRow, S> (source, selector));
}
- [MonoTODO]
public static EnumerableRowCollection<TRow> Where<TRow> (this TypedTableBase<TRow> source, Func<TRow, bool> predicate)
where TRow : DataRow
{
- throw new NotImplementedException ();
+ return new EnumerableRowCollection<TRow> (EnumerableRowCollection.Where<TRow> (source, predicate));
}
}
}
+2008-05-13 Atsushi Enomoto <atsushi@ximian.com>
+
+ * EnumerableRowCollectionTest.cs : added tests for orderby (though
+ commented out; they do not compile).
+
2008-05-13 Atsushi Enomoto <atsushi@ximian.com>
* DataRowComparerTest.cs, EnumerableRowCollectionTest.cs,
iterated = true;
}
}
+
+ [Test]
+ public void QueryWhereSelectOrderBy ()
+ {
+ var ds = new DataSet ();
+ ds.ReadXml ("Test/System.Data/testdataset1.xml");
+ var table = ds.Tables [0];
+ var q = from line in table.AsEnumerable ()
+ where line.Field<int> ("Score") >= 80
+ orderby line.Field<int> ("ID")
+ select new {
+ StudentID = line.Field<int> ("ID"),
+ StudentName = line.Field<string> ("Name"),
+ StudentScore = line.Field<int> ("Score") };
+ int prevID = -1;
+ foreach (var ql in q) {
+ switch (prevID) {
+ case -1:
+ Assert.AreEqual (4, ql.StudentID, "#1");
+ break;
+ case 4:
+ Assert.AreEqual (1, ql.StudentID, "#2");
+ break;
+ default:
+ Assert.Fail ("should match only one raw");
+ }
+ prevID = ql.StudentID;
+ }
+ }
+
+ [Test]
+ public void QueryWhereSelectOrderByDescending ()
+ {
+ var ds = new DataSet ();
+ ds.ReadXml ("Test/System.Data/testdataset1.xml");
+ var table = ds.Tables [0];
+ var q = from line in table.AsEnumerable ()
+ where line.Field<int> ("Score") >= 80
+ orderby line.Field<int> ("ID") descending
+ select new {
+ StudentID = line.Field<int> ("ID"),
+ StudentName = line.Field<string> ("Name"),
+ StudentScore = line.Field<int> ("Score") };
+ int prevID = -1;
+ foreach (var ql in q) {
+ switch (prevID) {
+ case -1:
+ Assert.AreEqual (1, ql.StudentID, "#1");
+ break;
+ case 4:
+ Assert.AreEqual (4, ql.StudentID, "#2");
+ break;
+ default:
+ Assert.Fail ("should match only one raw");
+ }
+ prevID = ql.StudentID;
+ }
+ }
*/
}
}