EnumerableRowCollection.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / DataSet / System / Data / EnumerableRowCollection.cs / 1 / EnumerableRowCollection.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
// [....]
//----------------------------------------------------------------------------- 
 
using System;
using System.Collections.Generic; 
using System.Collections;
using System.Text;
using System.Data;
using System.Linq; 
using System.Diagnostics;
using System.Linq.Expressions; 
using System.Collections.ObjectModel; 
using System.Data.DataSetExtensions;
 
namespace System.Data
{
    /// 
    /// Provides an entry point so that Cast operator call can be intercepted within an extension method. 
    /// 
    public abstract class EnumerableRowCollection : IEnumerable 
    { 
        internal abstract Type ElementType { get; }
        internal abstract DataTable Table { get; } 

        internal EnumerableRowCollection()
        {
        } 

        IEnumerator IEnumerable.GetEnumerator() 
        { 
            return null;
        } 
    }

    /// 
    /// This class provides a wrapper for DataTables to allow for querying via LINQ. 
    /// 
    public class EnumerableRowCollection : EnumerableRowCollection, IEnumerable 
    { 
        private readonly DataTable _table;
        private readonly IEnumerable _enumerableRows; 
        private readonly List> _listOfPredicates;

        // Stores list of sort expression in the order provided by user. E.g. order by, thenby, thenby descending..
        private readonly SortExpressionBuilder _sortExpression; 

        private readonly Func _selector; 
 
        #region Properties
 
        internal override Type ElementType
        {
            get
            { 
                return typeof(TRow);
            } 
 
        }
 
        internal IEnumerable EnumerableRows
        {
            get
            { 
                return _enumerableRows;
            } 
        } 

        internal override DataTable Table 
        {
            get
            {
                return _table; 
            }
        } 
 

        #endregion Properties 

        #region Constructors

        ///  
        /// This constructor is used when Select operator is called with output Type other than input row Type.
        /// Basically fail on GetLDV(), but other LINQ operators must work. 
        ///  
        internal EnumerableRowCollection(IEnumerable enumerableRows, bool isDataViewable, DataTable table)
        { 
            Debug.Assert(!isDataViewable || table != null, "isDataViewable bug table is null");

            _enumerableRows = enumerableRows;
            if (isDataViewable) 
            {
                _table = table; 
            } 
            _listOfPredicates = new List>();
            _sortExpression = new SortExpressionBuilder(); 
        }

        /// 
        /// Basic Constructor 
        /// 
        internal EnumerableRowCollection(DataTable table) 
        { 
            _table = table;
            _enumerableRows = table.Rows.Cast(); 
            _listOfPredicates = new List>();
            _sortExpression = new SortExpressionBuilder();
        }
 
        /// 
        /// Copy Constructor that sets the input IEnumerable as enumerableRows 
        /// Used to maintain IEnumerable that has linq operators executed in the same order as the user 
        /// 
        internal EnumerableRowCollection(EnumerableRowCollection source, IEnumerable enumerableRows, Func selector) 
        {
            Debug.Assert(null != enumerableRows, "null enumerableRows");

            _enumerableRows = enumerableRows; 
            _selector = selector;
            if (null != source) 
            { 
                if (null == source._selector)
                { 
                    _table = source._table;
                }
                _listOfPredicates = new List>(source._listOfPredicates);
                _sortExpression = source._sortExpression.Clone(); //deep copy the List 
            }
            else 
            { 
                _listOfPredicates = new List>();
                _sortExpression = new SortExpressionBuilder(); 
            }
        }

        #endregion Constructors 

        #region PublicInterface 
        IEnumerator IEnumerable.GetEnumerator() 
        {
            return GetEnumerator(); 
        }

        /// 
        ///  This method returns an strongly typed iterator 
        ///  for the underlying DataRow collection.
        ///  
        ///  
        ///   A strongly typed iterator.
        ///  
        public IEnumerator GetEnumerator()
        {
            return _enumerableRows.GetEnumerator();
        } 
        #endregion PublicInterface
 
        ///  
        /// Evaluates filter and sort if necessary and returns
        /// a LinqDataView representing the LINQ query this class has collected. 
        /// 
        /// LinqDataView repesenting the LINQ query
        internal LinqDataView GetLinqDataView() //Called by AsLinqDataView
        { 
            if ((null == _table) || !typeof(DataRow).IsAssignableFrom(typeof(TRow)))
            { 
                throw DataSetUtil.NotSupported(Strings.ToLDVUnsupported); 
            }
 
            LinqDataView view = null;

            #region BuildSinglePredicate
 
            Func finalPredicate = null; //Conjunction of all .Where(..) predicates
            if ((null != _selector) && (0 < _listOfPredicates.Count)) 
            { 
                // Hook up all individual predicates into one predicate
                // This delegate is a conjunction of multiple predicates set by the user 
                // Note: This is a Short-Circuit Conjunction
                finalPredicate =
                    delegate(DataRow row)
                    { 
                        if (!Object.ReferenceEquals(row, _selector((TRow)(object)row)))
                        { 
                            throw DataSetUtil.NotSupported(Strings.ToLDVUnsupported); 
                        }
                        foreach (Func pred in _listOfPredicates) 
                        {
                            if (!pred((TRow)(object)row))
                            {
                                return false; 
                            }
                        } 
                        return true; 
                    };
            } 
            else if (null != _selector)
            {
                finalPredicate =
                    delegate(DataRow row) 
                    {
                        if (!Object.ReferenceEquals(row, _selector((TRow)(object)row))) 
                        { 
                            throw DataSetUtil.NotSupported(Strings.ToLDVUnsupported);
                        } 
                        return true;
                    };
            }
            else if (0 < _listOfPredicates.Count) 
            {
                finalPredicate = 
                    delegate(DataRow row) 
                    {
                        foreach (Func pred in _listOfPredicates) 
                        {
                            if (!pred((TRow)(object)row))
                            {
                                return false; 
                            }
                        } 
                        return true; 
                    };
            } 
            #endregion BuildSinglePredicate

            #region Evaluate Filter/Sort
            //  All of this mess below is because we want to create index only once. 
            //
            //  If we only have filter, we set _view.Predicate       - 1 index creation 
            //  If we only have sort, we set _view.SortExpression()  - 1 index creation 
            //  If we have BOTH, we set them through the constructor - 1 index creation
            // 

            // Filter AND Sort
            if ((null != finalPredicate) && (0 < _sortExpression.Count))
            { 
                // A lot more work here because constructor does not know type K,
                // so the responsibility to create appropriate delegate comparers 
                // is outside of the constructor. 

                view = new LinqDataView( 
                               _table,
                               finalPredicate,                      //Func() Predicate
                               delegate(DataRow row)                //System.Predicate
                               { 
                                   return finalPredicate(row);
                               }, 
                               delegate(DataRow a, DataRow b)       //Comparison for DV for Index creation 
                               {
                                   return _sortExpression.Compare( 
                                            _sortExpression.Select((TRow)(object)a),
                                            _sortExpression.Select((TRow)(object)b)
                                       );
                               }, 
                               delegate(object key, DataRow row)    //Comparison_K_T for DV's Find()
                               { 
                                   return _sortExpression.Compare( 
                                        (List)key,
                                        _sortExpression.Select((TRow)(object)row) 
                                      );
                               },
                                _sortExpression.CloneCast());
            } 
            else if (null != finalPredicate)
            { 
                //Only Filtering 
                view = new LinqDataView(
                                    _table, 
                                    finalPredicate,
                                    delegate(DataRow row)                //System.Predicate
                                    {
                                        return finalPredicate(row); 
                                    },
                                    null, 
                                    null, 
                                    _sortExpression.CloneCast());
            } 
            else if (0 < _sortExpression.Count)
            {
                //Only Sorting
                view = new LinqDataView( 
                            _table,
                            null, 
                            null, 
                            delegate(DataRow a, DataRow b)
                            { 
                                return _sortExpression.Compare(_sortExpression.Select((TRow)(object)a), _sortExpression.Select((TRow)(object)b));
                            },
                            delegate(object key, DataRow row)
                            { 
                                return _sortExpression.Compare((List)key, _sortExpression.Select((TRow)(object)row));
                            }, 
                            _sortExpression.CloneCast()); 
            }
            else 
            {
                view = new LinqDataView(_table, _sortExpression.CloneCast());
            }
            #endregion Evaluate Filter and Sort 

            return view; 
        } 

 
        #region Add Single Filter/Sort Expression

        /// 
        /// Used to add a filter predicate. 
        /// A conjunction of all predicates are evaluated in LinqDataView
        ///  
        internal void AddPredicate(Func pred) 
        {
            Debug.Assert(pred != null); 
            _listOfPredicates.Add(pred);
        }

        ///  
        /// Adds a sort expression when Keyselector is provided but not Comparer
        ///  
        internal void AddSortExpression(Func keySelector, bool isDescending, bool isOrderBy) 
        {
            AddSortExpression(keySelector, Comparer.Default, isDescending, isOrderBy); 
        }

        /// 
        /// Adds a sort expression when Keyselector and Comparer are provided. 
        /// 
        internal void AddSortExpression( 
                            Func keySelector, 
                            IComparer comparer,
                            bool isDescending, 
                            bool isOrderBy)
        {
            DataSetUtil.CheckArgumentNull(keySelector, "keySelector");
            DataSetUtil.CheckArgumentNull(comparer, "comparer"); 

            _sortExpression.Add( 
                    delegate(TRow input) 
                    {
                        return (object)keySelector(input); 
                    },
                    delegate(object val1, object val2)
                    {
                        return (isDescending ? -1 : 1) * comparer.Compare((TKey)val1, (TKey)val2); 
                    },
                      isOrderBy); 
        } 

        #endregion Add Single Filter/Sort Expression 

    }

} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
// [....]
//----------------------------------------------------------------------------- 
 
using System;
using System.Collections.Generic; 
using System.Collections;
using System.Text;
using System.Data;
using System.Linq; 
using System.Diagnostics;
using System.Linq.Expressions; 
using System.Collections.ObjectModel; 
using System.Data.DataSetExtensions;
 
namespace System.Data
{
    /// 
    /// Provides an entry point so that Cast operator call can be intercepted within an extension method. 
    /// 
    public abstract class EnumerableRowCollection : IEnumerable 
    { 
        internal abstract Type ElementType { get; }
        internal abstract DataTable Table { get; } 

        internal EnumerableRowCollection()
        {
        } 

        IEnumerator IEnumerable.GetEnumerator() 
        { 
            return null;
        } 
    }

    /// 
    /// This class provides a wrapper for DataTables to allow for querying via LINQ. 
    /// 
    public class EnumerableRowCollection : EnumerableRowCollection, IEnumerable 
    { 
        private readonly DataTable _table;
        private readonly IEnumerable _enumerableRows; 
        private readonly List> _listOfPredicates;

        // Stores list of sort expression in the order provided by user. E.g. order by, thenby, thenby descending..
        private readonly SortExpressionBuilder _sortExpression; 

        private readonly Func _selector; 
 
        #region Properties
 
        internal override Type ElementType
        {
            get
            { 
                return typeof(TRow);
            } 
 
        }
 
        internal IEnumerable EnumerableRows
        {
            get
            { 
                return _enumerableRows;
            } 
        } 

        internal override DataTable Table 
        {
            get
            {
                return _table; 
            }
        } 
 

        #endregion Properties 

        #region Constructors

        ///  
        /// This constructor is used when Select operator is called with output Type other than input row Type.
        /// Basically fail on GetLDV(), but other LINQ operators must work. 
        ///  
        internal EnumerableRowCollection(IEnumerable enumerableRows, bool isDataViewable, DataTable table)
        { 
            Debug.Assert(!isDataViewable || table != null, "isDataViewable bug table is null");

            _enumerableRows = enumerableRows;
            if (isDataViewable) 
            {
                _table = table; 
            } 
            _listOfPredicates = new List>();
            _sortExpression = new SortExpressionBuilder(); 
        }

        /// 
        /// Basic Constructor 
        /// 
        internal EnumerableRowCollection(DataTable table) 
        { 
            _table = table;
            _enumerableRows = table.Rows.Cast(); 
            _listOfPredicates = new List>();
            _sortExpression = new SortExpressionBuilder();
        }
 
        /// 
        /// Copy Constructor that sets the input IEnumerable as enumerableRows 
        /// Used to maintain IEnumerable that has linq operators executed in the same order as the user 
        /// 
        internal EnumerableRowCollection(EnumerableRowCollection source, IEnumerable enumerableRows, Func selector) 
        {
            Debug.Assert(null != enumerableRows, "null enumerableRows");

            _enumerableRows = enumerableRows; 
            _selector = selector;
            if (null != source) 
            { 
                if (null == source._selector)
                { 
                    _table = source._table;
                }
                _listOfPredicates = new List>(source._listOfPredicates);
                _sortExpression = source._sortExpression.Clone(); //deep copy the List 
            }
            else 
            { 
                _listOfPredicates = new List>();
                _sortExpression = new SortExpressionBuilder(); 
            }
        }

        #endregion Constructors 

        #region PublicInterface 
        IEnumerator IEnumerable.GetEnumerator() 
        {
            return GetEnumerator(); 
        }

        /// 
        ///  This method returns an strongly typed iterator 
        ///  for the underlying DataRow collection.
        ///  
        ///  
        ///   A strongly typed iterator.
        ///  
        public IEnumerator GetEnumerator()
        {
            return _enumerableRows.GetEnumerator();
        } 
        #endregion PublicInterface
 
        ///  
        /// Evaluates filter and sort if necessary and returns
        /// a LinqDataView representing the LINQ query this class has collected. 
        /// 
        /// LinqDataView repesenting the LINQ query
        internal LinqDataView GetLinqDataView() //Called by AsLinqDataView
        { 
            if ((null == _table) || !typeof(DataRow).IsAssignableFrom(typeof(TRow)))
            { 
                throw DataSetUtil.NotSupported(Strings.ToLDVUnsupported); 
            }
 
            LinqDataView view = null;

            #region BuildSinglePredicate
 
            Func finalPredicate = null; //Conjunction of all .Where(..) predicates
            if ((null != _selector) && (0 < _listOfPredicates.Count)) 
            { 
                // Hook up all individual predicates into one predicate
                // This delegate is a conjunction of multiple predicates set by the user 
                // Note: This is a Short-Circuit Conjunction
                finalPredicate =
                    delegate(DataRow row)
                    { 
                        if (!Object.ReferenceEquals(row, _selector((TRow)(object)row)))
                        { 
                            throw DataSetUtil.NotSupported(Strings.ToLDVUnsupported); 
                        }
                        foreach (Func pred in _listOfPredicates) 
                        {
                            if (!pred((TRow)(object)row))
                            {
                                return false; 
                            }
                        } 
                        return true; 
                    };
            } 
            else if (null != _selector)
            {
                finalPredicate =
                    delegate(DataRow row) 
                    {
                        if (!Object.ReferenceEquals(row, _selector((TRow)(object)row))) 
                        { 
                            throw DataSetUtil.NotSupported(Strings.ToLDVUnsupported);
                        } 
                        return true;
                    };
            }
            else if (0 < _listOfPredicates.Count) 
            {
                finalPredicate = 
                    delegate(DataRow row) 
                    {
                        foreach (Func pred in _listOfPredicates) 
                        {
                            if (!pred((TRow)(object)row))
                            {
                                return false; 
                            }
                        } 
                        return true; 
                    };
            } 
            #endregion BuildSinglePredicate

            #region Evaluate Filter/Sort
            //  All of this mess below is because we want to create index only once. 
            //
            //  If we only have filter, we set _view.Predicate       - 1 index creation 
            //  If we only have sort, we set _view.SortExpression()  - 1 index creation 
            //  If we have BOTH, we set them through the constructor - 1 index creation
            // 

            // Filter AND Sort
            if ((null != finalPredicate) && (0 < _sortExpression.Count))
            { 
                // A lot more work here because constructor does not know type K,
                // so the responsibility to create appropriate delegate comparers 
                // is outside of the constructor. 

                view = new LinqDataView( 
                               _table,
                               finalPredicate,                      //Func() Predicate
                               delegate(DataRow row)                //System.Predicate
                               { 
                                   return finalPredicate(row);
                               }, 
                               delegate(DataRow a, DataRow b)       //Comparison for DV for Index creation 
                               {
                                   return _sortExpression.Compare( 
                                            _sortExpression.Select((TRow)(object)a),
                                            _sortExpression.Select((TRow)(object)b)
                                       );
                               }, 
                               delegate(object key, DataRow row)    //Comparison_K_T for DV's Find()
                               { 
                                   return _sortExpression.Compare( 
                                        (List)key,
                                        _sortExpression.Select((TRow)(object)row) 
                                      );
                               },
                                _sortExpression.CloneCast());
            } 
            else if (null != finalPredicate)
            { 
                //Only Filtering 
                view = new LinqDataView(
                                    _table, 
                                    finalPredicate,
                                    delegate(DataRow row)                //System.Predicate
                                    {
                                        return finalPredicate(row); 
                                    },
                                    null, 
                                    null, 
                                    _sortExpression.CloneCast());
            } 
            else if (0 < _sortExpression.Count)
            {
                //Only Sorting
                view = new LinqDataView( 
                            _table,
                            null, 
                            null, 
                            delegate(DataRow a, DataRow b)
                            { 
                                return _sortExpression.Compare(_sortExpression.Select((TRow)(object)a), _sortExpression.Select((TRow)(object)b));
                            },
                            delegate(object key, DataRow row)
                            { 
                                return _sortExpression.Compare((List)key, _sortExpression.Select((TRow)(object)row));
                            }, 
                            _sortExpression.CloneCast()); 
            }
            else 
            {
                view = new LinqDataView(_table, _sortExpression.CloneCast());
            }
            #endregion Evaluate Filter and Sort 

            return view; 
        } 

 
        #region Add Single Filter/Sort Expression

        /// 
        /// Used to add a filter predicate. 
        /// A conjunction of all predicates are evaluated in LinqDataView
        ///  
        internal void AddPredicate(Func pred) 
        {
            Debug.Assert(pred != null); 
            _listOfPredicates.Add(pred);
        }

        ///  
        /// Adds a sort expression when Keyselector is provided but not Comparer
        ///  
        internal void AddSortExpression(Func keySelector, bool isDescending, bool isOrderBy) 
        {
            AddSortExpression(keySelector, Comparer.Default, isDescending, isOrderBy); 
        }

        /// 
        /// Adds a sort expression when Keyselector and Comparer are provided. 
        /// 
        internal void AddSortExpression( 
                            Func keySelector, 
                            IComparer comparer,
                            bool isDescending, 
                            bool isOrderBy)
        {
            DataSetUtil.CheckArgumentNull(keySelector, "keySelector");
            DataSetUtil.CheckArgumentNull(comparer, "comparer"); 

            _sortExpression.Add( 
                    delegate(TRow input) 
                    {
                        return (object)keySelector(input); 
                    },
                    delegate(object val1, object val2)
                    {
                        return (isDescending ? -1 : 1) * comparer.Compare((TKey)val1, (TKey)val2); 
                    },
                      isOrderBy); 
        } 

        #endregion Add Single Filter/Sort Expression 

    }

} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK