You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@ -0,0 +1,280 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="DataTableExtenstions.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using System.Linq.Expressions;
|
||||
using System.Globalization;
|
||||
using System.Diagnostics;
|
||||
using System.Data.DataSetExtensions;
|
||||
|
||||
namespace System.Data
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// This static class defines the DataTable extension methods.
|
||||
/// </summary>
|
||||
public static class DataTableExtensions
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// This method returns a IEnumerable of Datarows.
|
||||
/// </summary>
|
||||
/// <param name="source">
|
||||
/// The source DataTable to make enumerable.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// IEnumerable of datarows.
|
||||
/// </returns>
|
||||
public static EnumerableRowCollection<DataRow> AsEnumerable(this DataTable source)
|
||||
{
|
||||
DataSetUtil.CheckArgumentNull(source, "source");
|
||||
return new EnumerableRowCollection<DataRow>(source);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method takes an input sequence of DataRows and produces a DataTable object
|
||||
/// with copies of the source rows.
|
||||
/// Also note that this will cause the rest of the query to execute at this point in time
|
||||
/// (e.g. there is no more delayed execution after this sequence operator).
|
||||
/// </summary>
|
||||
/// <param name="source">
|
||||
/// The input sequence of DataRows
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// DataTable containing copies of the source DataRows.
|
||||
/// Properties for the DataTable table will be taken from first DataRow in the source.
|
||||
/// </returns>
|
||||
/// <exception cref="ArgumentNullException">if source is null</exception>
|
||||
/// <exception cref="InvalidOperationException">if source is empty</exception>
|
||||
public static DataTable CopyToDataTable<T>(this IEnumerable<T> source)
|
||||
where T : DataRow
|
||||
{
|
||||
DataSetUtil.CheckArgumentNull(source, "source");
|
||||
return LoadTableFromEnumerable(source, null, null, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// delegates to other CopyToDataTable overload with a null FillErrorEventHandler.
|
||||
/// </summary>
|
||||
public static void CopyToDataTable<T>(this IEnumerable<T> source, DataTable table, LoadOption options)
|
||||
where T : DataRow
|
||||
{
|
||||
DataSetUtil.CheckArgumentNull(source, "source");
|
||||
DataSetUtil.CheckArgumentNull(table, "table");
|
||||
LoadTableFromEnumerable(source, table, options, null);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// This method takes an input sequence of DataRows and produces a DataTable object
|
||||
/// with copies of the source rows.
|
||||
/// Also note that this will cause the rest of the query to execute at this point in time
|
||||
/// (e.g. there is no more delayed execution after this sequence operator).
|
||||
/// </summary>
|
||||
/// <param name="source">
|
||||
/// The input sequence of DataRows
|
||||
///
|
||||
/// CopyToDataTable uses DataRowVersion.Default when retrieving values from source DataRow
|
||||
/// which will include proposed values for DataRow being edited.
|
||||
///
|
||||
/// Null DataRow in the sequence are skipped.
|
||||
/// </param>
|
||||
/// <param name="table">
|
||||
/// The target DataTable to load.
|
||||
/// </param>
|
||||
/// <param name="options">
|
||||
/// The target DataTable to load.
|
||||
/// </param>
|
||||
/// <param name="errorHandler">
|
||||
/// Error handler for recoverable errors.
|
||||
/// Recoverable errors include:
|
||||
/// A source DataRow is in the deleted or detached state state.
|
||||
/// DataTable.LoadDataRow threw an exception, i.e. wrong # of columns in source row
|
||||
/// Unrecoverable errors include:
|
||||
/// exceptions from IEnumerator, DataTable.BeginLoadData or DataTable.EndLoadData
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// DataTable containing copies of the source DataRows.
|
||||
/// </returns>
|
||||
/// <exception cref="ArgumentNullException">if source is null</exception>
|
||||
/// <exception cref="ArgumentNullException">if table is null</exception>
|
||||
/// <exception cref="InvalidOperationException">if source DataRow is in Deleted or Detached state</exception>
|
||||
public static void CopyToDataTable<T>(this IEnumerable<T> source, DataTable table, LoadOption options, FillErrorEventHandler errorHandler)
|
||||
where T : DataRow
|
||||
{
|
||||
DataSetUtil.CheckArgumentNull(source, "source");
|
||||
DataSetUtil.CheckArgumentNull(table, "table");
|
||||
LoadTableFromEnumerable(source, table, options, errorHandler);
|
||||
}
|
||||
|
||||
private static DataTable LoadTableFromEnumerable<T>(IEnumerable<T> source, DataTable table, LoadOption? options, FillErrorEventHandler errorHandler)
|
||||
where T : DataRow
|
||||
{
|
||||
if (options.HasValue) {
|
||||
switch(options.Value) {
|
||||
case LoadOption.OverwriteChanges:
|
||||
case LoadOption.PreserveChanges:
|
||||
case LoadOption.Upsert:
|
||||
break;
|
||||
default:
|
||||
throw DataSetUtil.InvalidLoadOption(options.Value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
using (IEnumerator<T> rows = source.GetEnumerator())
|
||||
{
|
||||
// need to get first row to create table
|
||||
if (!rows.MoveNext())
|
||||
{
|
||||
if (table == null)
|
||||
{
|
||||
throw DataSetUtil.InvalidOperation(Strings.DataSetLinq_EmptyDataRowSource);
|
||||
}
|
||||
else
|
||||
{
|
||||
return table;
|
||||
}
|
||||
}
|
||||
|
||||
DataRow current;
|
||||
if (table == null)
|
||||
{
|
||||
current = rows.Current;
|
||||
if (current == null)
|
||||
{
|
||||
throw DataSetUtil.InvalidOperation(Strings.DataSetLinq_NullDataRow);
|
||||
}
|
||||
|
||||
table = new DataTable();
|
||||
table.Locale = CultureInfo.CurrentCulture;
|
||||
// We do not copy the same properties that DataView.ToTable does.
|
||||
// If user needs that functionality, use other CopyToDataTable overloads.
|
||||
// The reasoning being, the IEnumerator<DataRow> can be sourced from
|
||||
// different DataTable, so we just use the "Default" instead of resolving the difference.
|
||||
|
||||
foreach (DataColumn column in current.Table.Columns)
|
||||
{
|
||||
table.Columns.Add(column.ColumnName, column.DataType);
|
||||
}
|
||||
}
|
||||
|
||||
table.BeginLoadData();
|
||||
try
|
||||
{
|
||||
do
|
||||
{
|
||||
current = rows.Current;
|
||||
if (current == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
object[] values = null;
|
||||
try
|
||||
{ // 'recoverable' error block
|
||||
switch(current.RowState)
|
||||
{
|
||||
case DataRowState.Detached:
|
||||
if (!current.HasVersion(DataRowVersion.Proposed))
|
||||
{
|
||||
throw DataSetUtil.InvalidOperation(Strings.DataSetLinq_CannotLoadDetachedRow);
|
||||
}
|
||||
goto case DataRowState.Added;
|
||||
case DataRowState.Unchanged:
|
||||
case DataRowState.Added:
|
||||
case DataRowState.Modified:
|
||||
values = current.ItemArray;
|
||||
if (options.HasValue)
|
||||
{
|
||||
table.LoadDataRow(values, options.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
table.LoadDataRow(values, true);
|
||||
}
|
||||
break;
|
||||
case DataRowState.Deleted:
|
||||
throw DataSetUtil.InvalidOperation(Strings.DataSetLinq_CannotLoadDeletedRow);
|
||||
default:
|
||||
throw DataSetUtil.InvalidDataRowState(current.RowState);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (!DataSetUtil.IsCatchableExceptionType(e))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
FillErrorEventArgs fillError = null;
|
||||
if (null != errorHandler)
|
||||
{
|
||||
fillError = new FillErrorEventArgs(table, values);
|
||||
fillError.Errors = e;
|
||||
errorHandler.Invoke(rows, fillError);
|
||||
}
|
||||
if (null == fillError) {
|
||||
throw;
|
||||
}
|
||||
else if (!fillError.Continue)
|
||||
{
|
||||
if (Object.ReferenceEquals(fillError.Errors ?? e, e))
|
||||
{ // if user didn't change exception to throw (or set it to null)
|
||||
throw;
|
||||
}
|
||||
else
|
||||
{ // user may have changed exception to throw in handler
|
||||
throw fillError.Errors;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (rows.MoveNext());
|
||||
}
|
||||
finally
|
||||
{
|
||||
table.EndLoadData();
|
||||
}
|
||||
}
|
||||
Debug.Assert(null != table, "null DataTable");
|
||||
return table;
|
||||
}
|
||||
|
||||
#region Methods to Create LinqDataView
|
||||
|
||||
/// <summary>
|
||||
/// Creates a LinkDataView of DataRow over the input table.
|
||||
/// </summary>
|
||||
/// <param name="table">DataTable that the view is over.</param>
|
||||
/// <returns>An instance of LinkDataView.</returns>
|
||||
public static DataView AsDataView(this DataTable table)
|
||||
{
|
||||
DataSetUtil.CheckArgumentNull<DataTable>(table, "table");
|
||||
return new LinqDataView(table, null);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates a LinqDataView from EnumerableDataTable
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of the row in the table. Must inherit from DataRow</typeparam>
|
||||
/// <param name="source">The enumerable-datatable over which view must be created.</param>
|
||||
/// <returns>Generated LinkDataView of type T</returns>
|
||||
public static DataView AsDataView<T>(this EnumerableRowCollection<T> source) where T : DataRow
|
||||
{
|
||||
DataSetUtil.CheckArgumentNull<EnumerableRowCollection<T>>(source, "source");
|
||||
return source.GetLinqDataView();
|
||||
}
|
||||
|
||||
#endregion LinqDataView
|
||||
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user