cc1ff7a80325006d7cc99b60fededd234ba4840e
[mono.git] / mcs / class / referencesource / System.Data.DataSetExtensions / System / Data / EnumerableRowCollectionExtensions.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="EnumRowCollectionExtensions.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 // <owner current="true" primary="true">Microsoft</owner>
6 // <owner current="true" primary="false">Microsoft</owner>
7 //------------------------------------------------------------------------------
8
9 using System;
10 using System.Collections.Generic;
11 using System.Linq;
12 using System.Linq.Expressions;
13 using System.Globalization;
14 using System.Diagnostics;
15
16 namespace System.Data
17 {
18     /// <summary>
19     /// This static class defines the extension methods that add LINQ operator functionality
20     /// within IEnumerableDT and IOrderedEnumerableDT.
21     /// </summary>
22     public static class EnumerableRowCollectionExtensions
23     {
24         /// <summary>
25         /// LINQ's Where operator for generic EnumerableRowCollection.
26         /// </summary>
27         public static EnumerableRowCollection<TRow> Where<TRow>(
28                                                 this EnumerableRowCollection<TRow> source,
29                                                 Func<TRow, bool> predicate)
30         {
31             EnumerableRowCollection<TRow> edt =
32                 new EnumerableRowCollection<TRow>(source, Enumerable.Where<TRow>(source, predicate), null); //copy constructor
33             edt.AddPredicate(predicate);
34             return edt;
35         }
36
37         /// <summary>
38         /// LINQ's OrderBy operator for generic EnumerableRowCollection.
39         /// </summary>
40         public static OrderedEnumerableRowCollection<TRow> OrderBy<TRow, TKey>(
41                                                         this EnumerableRowCollection<TRow> source,
42                                                         Func<TRow, TKey> keySelector)
43         {
44             IEnumerable<TRow> ie = Enumerable.OrderBy<TRow, TKey>(source, keySelector);
45
46             OrderedEnumerableRowCollection<TRow> edt = new OrderedEnumerableRowCollection<TRow>(source, ie);
47             edt.AddSortExpression(keySelector, false, true);
48             return edt;
49         }
50
51         /// <summary>
52         /// LINQ's OrderBy operator for generic EnumerableRowCollection.
53         /// </summary>
54         public static OrderedEnumerableRowCollection<TRow> OrderBy<TRow, TKey>(
55                                                         this EnumerableRowCollection<TRow> source,
56                                                         Func<TRow, TKey> keySelector,
57                                                         IComparer<TKey> comparer)
58         {
59             IEnumerable<TRow> ie = Enumerable.OrderBy<TRow, TKey>(source, keySelector, comparer);
60             OrderedEnumerableRowCollection<TRow> edt = new OrderedEnumerableRowCollection<TRow>(source, ie);
61             edt.AddSortExpression(keySelector, comparer, false, true);
62             return edt;
63         }
64
65         /// <summary>
66         /// LINQ's OrderByDescending operator for generic EnumerableRowCollection.
67         /// </summary>
68         public static OrderedEnumerableRowCollection<TRow> OrderByDescending<TRow, TKey>(
69                                                         this EnumerableRowCollection<TRow> source,
70                                                         Func<TRow, TKey> keySelector)
71         {
72             IEnumerable<TRow> ie = Enumerable.OrderByDescending<TRow, TKey>(source, keySelector);
73
74             OrderedEnumerableRowCollection<TRow> edt = new OrderedEnumerableRowCollection<TRow>(source, ie);
75             edt.AddSortExpression(keySelector, true, true);
76             return edt;
77         }
78
79         /// <summary>
80         /// LINQ's OrderByDescending operator for generic EnumerableRowCollection.
81         /// </summary>
82         public static OrderedEnumerableRowCollection<TRow> OrderByDescending<TRow, TKey>(
83                                                         this EnumerableRowCollection<TRow> source,
84                                                         Func<TRow, TKey> keySelector,
85                                                         IComparer<TKey> comparer)
86         {
87             IEnumerable<TRow> ie = Enumerable.OrderByDescending<TRow, TKey>(source, keySelector, comparer);
88
89             OrderedEnumerableRowCollection<TRow> edt = new OrderedEnumerableRowCollection<TRow>(source, ie);
90             edt.AddSortExpression(keySelector, comparer, true, true);
91             return edt;
92         }
93
94         /// <summary>
95         /// LINQ's ThenBy operator for generic EnumerableRowCollection.
96         /// </summary>
97         public static OrderedEnumerableRowCollection<TRow> ThenBy<TRow, TKey>(
98                                                         this OrderedEnumerableRowCollection<TRow> source,
99                                                         Func<TRow, TKey> keySelector)
100         {
101             IEnumerable<TRow> ie =
102                 Enumerable.ThenBy<TRow, TKey>((IOrderedEnumerable<TRow>)source.EnumerableRows, keySelector);
103
104             OrderedEnumerableRowCollection<TRow> edt =
105                 new OrderedEnumerableRowCollection<TRow>((EnumerableRowCollection<TRow>)source, ie);
106
107             edt.AddSortExpression(keySelector, /*isDesc*/ false, /*isOrderBy*/ false);
108             return edt;
109         }
110
111         /// <summary>
112         /// LINQ's ThenBy operator for generic EnumerableRowCollection.
113         /// </summary>
114         public static OrderedEnumerableRowCollection<TRow> ThenBy<TRow, TKey>(
115                                                         this OrderedEnumerableRowCollection<TRow> source,
116                                                         Func<TRow, TKey> keySelector,
117                                                         IComparer<TKey> comparer)
118         {
119             IEnumerable<TRow> ie =
120                 Enumerable.ThenBy<TRow, TKey>((IOrderedEnumerable<TRow>)source.EnumerableRows, keySelector, comparer);
121
122             OrderedEnumerableRowCollection<TRow> edt =
123                 new OrderedEnumerableRowCollection<TRow>((EnumerableRowCollection<TRow>)source, ie);
124
125             edt.AddSortExpression(keySelector, comparer, false, false);
126             return edt;
127         }
128
129         /// <summary>
130         /// LINQ's ThenByDescending operator for generic EnumerableRowCollection.
131         /// </summary>
132         public static OrderedEnumerableRowCollection<TRow> ThenByDescending<TRow, TKey>(
133                                                         this OrderedEnumerableRowCollection<TRow> source,
134                                                         Func<TRow, TKey> keySelector)
135         {
136             IEnumerable<TRow> ie =
137                 Enumerable.ThenByDescending<TRow, TKey>((IOrderedEnumerable<TRow>)source.EnumerableRows, keySelector);
138
139             OrderedEnumerableRowCollection<TRow> edt =
140                 new OrderedEnumerableRowCollection<TRow>((EnumerableRowCollection<TRow>)source, ie);
141
142             edt.AddSortExpression(keySelector, /*desc*/ true, false);
143             return edt;
144         }
145
146         /// <summary>
147         /// LINQ's ThenByDescending operator for generic EnumerableRowCollection.
148         /// </summary>
149         public static OrderedEnumerableRowCollection<TRow> ThenByDescending<TRow, TKey>(
150                                                         this OrderedEnumerableRowCollection<TRow> source,
151                                                         Func<TRow, TKey> keySelector,
152                                                         IComparer<TKey> comparer)
153         {
154             IEnumerable<TRow> ie =
155                 Enumerable.ThenByDescending<TRow, TKey>((IOrderedEnumerable<TRow>)source.EnumerableRows, keySelector, comparer);
156
157             OrderedEnumerableRowCollection<TRow> edt =
158                 new OrderedEnumerableRowCollection<TRow>((EnumerableRowCollection<TRow>)source, ie);
159
160             edt.AddSortExpression(keySelector, comparer, true, false);
161             return edt;
162         }
163
164         /// <summary>
165         /// Executes a Select (Projection) on EnumerableDataTable. If the selector returns a different
166         /// type than the type of rows, then AsLinqDataView is disabled, and the returning EnumerableDataTable
167         /// represents an enumerable over the LINQ Query.
168         /// </summary>
169         public static EnumerableRowCollection<S> Select<TRow, S>(
170                                                 this EnumerableRowCollection<TRow> source,
171                                                 Func<TRow, S> selector)
172         {
173             //Anonymous type or some other type
174             //The only thing that matters from this point on is _enumerableRows
175
176             IEnumerable<S> typedEnumerable = Enumerable.Select<TRow, S>(source, selector);
177
178             // Dont need predicates or sort expression from this point on since we know
179             // AsLinqDataView is disabled.
180             return new EnumerableRowCollection<S>(((object)source) as EnumerableRowCollection<S>,
181                                                   typedEnumerable,
182                                                   ((object)selector) as Func<S,S>);
183         }
184
185         /// <summary>
186         /// Casts an EnumerableDataTable_TSource into EnumerableDataTable_TResult
187         /// </summary>
188         public static EnumerableRowCollection<TResult> Cast<TResult>(this EnumerableRowCollection source)
189         {
190             // Since Cast does not have the signature Cast_T_R(..) this call is routed
191             // through the non-generic base class EnumerableDataTable
192
193             if ((null != source) && source.ElementType.Equals(typeof(TResult)))
194             {
195                 return (EnumerableRowCollection<TResult>)(object)source;
196             }
197             else
198             {   //Anonymous type or some other type
199                 //The only thing that matters from this point on is _enumerableRows
200
201                 IEnumerable<TResult> typedEnumerable = Enumerable.Cast<TResult>(source);
202
203                 EnumerableRowCollection<TResult> newEdt = new EnumerableRowCollection<TResult>(
204                     typedEnumerable,
205                     typeof(TResult).IsAssignableFrom(source.ElementType) && typeof(DataRow).IsAssignableFrom(typeof(TResult)),
206                     source.Table);
207
208                 return newEdt;
209             }
210         }
211     } //end class
212 }