diff --git a/src/System.Management.Automation/engine/CoreAdapter.cs b/src/System.Management.Automation/engine/CoreAdapter.cs
index 70e25a3a1f5..4fbf9d629e7 100644
--- a/src/System.Management.Automation/engine/CoreAdapter.cs
+++ b/src/System.Management.Automation/engine/CoreAdapter.cs
@@ -6,6 +6,7 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
+using System.Data;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Dynamic;
@@ -5007,6 +5008,221 @@ private static XmlNode[] FindNodes(object obj, string propertyName, StringCompar
}
}
+ ///
+ /// Deals with DataRow objects
+ ///
+ internal class DataRowAdapter : PropertyOnlyAdapter
+ {
+ #region virtual
+ ///
+ /// Retrieves all the properties available in the object.
+ ///
+ /// object to get all the property information from
+ /// collection where the members will be added
+ protected override void DoAddAllProperties(object obj, PSMemberInfoInternalCollection members)
+ {
+ DataRow dataRow = (DataRow)obj;
+ if (dataRow.Table == null || dataRow.Table.Columns == null)
+ {
+ return;
+ }
+
+ foreach (DataColumn property in dataRow.Table.Columns)
+ {
+ members.Add(new PSProperty(property.ColumnName, this, obj, property.ColumnName) as T);
+ }
+
+ return;
+ }
+ ///
+ /// Returns null if propertyName is not a property in the adapter or
+ /// the corresponding PSProperty with its adapterData set to information
+ /// to be used when retrieving the property.
+ ///
+ /// object to retrieve the PSProperty from
+ /// name of the property to be retrieved
+ /// The PSProperty corresponding to propertyName from obj
+ protected override PSProperty DoGetProperty(object obj, string propertyName)
+ {
+ DataRow dataRow = (DataRow)obj;
+
+ if (!dataRow.Table.Columns.Contains(propertyName))
+ {
+ return null;
+ }
+
+ string columnName = dataRow.Table.Columns[propertyName].ColumnName;
+ return new PSProperty(columnName, this, obj, columnName);
+ }
+
+ ///
+ /// Returns the name of the type corresponding to the property
+ ///
+ /// PSProperty obtained in a previous DoGetProperty
+ /// True if the result is for display purposes only
+ /// the name of the type corresponding to the property
+ protected override string PropertyType(PSProperty property, bool forDisplay)
+ {
+ string columnName = (string)property.adapterData;
+ DataRow dataRow = (DataRow)property.baseObject;
+ var dataType = dataRow.Table.Columns[columnName].DataType;
+ return forDisplay ? ToStringCodeMethods.Type(dataType) : dataType.FullName;
+ }
+
+ ///
+ /// Returns true if the property is settable
+ ///
+ /// property to check
+ /// true if the property is settable
+ protected override bool PropertyIsSettable(PSProperty property)
+ {
+ string columnName = (string)property.adapterData;
+ DataRow dataRow = (DataRow)property.baseObject;
+ return !dataRow.Table.Columns[columnName].ReadOnly;
+ }
+
+ ///
+ /// Returns true if the property is gettable
+ ///
+ /// property to check
+ /// true if the property is gettable
+ protected override bool PropertyIsGettable(PSProperty property)
+ {
+ return true;
+ }
+
+
+ ///
+ /// Returns the value from a property coming from a previous call to DoGetProperty
+ ///
+ /// PSProperty coming from a previous call to DoGetProperty
+ /// The value of the property
+ protected override object PropertyGet(PSProperty property)
+ {
+ DataRow dataRow = (DataRow)property.baseObject;
+ return dataRow[(string)property.adapterData];
+ }
+ ///
+ /// Sets the value of a property coming from a previous call to DoGetProperty
+ ///
+ /// PSProperty coming from a previous call to DoGetProperty
+ /// value to set the property with
+ /// instructs the adapter to convert before setting, if the adapter supports conversion
+ protected override void PropertySet(PSProperty property, object setValue, bool convertIfPossible)
+ {
+ DataRow dataRow = (DataRow)property.baseObject;
+ dataRow[(string)property.adapterData] = setValue;
+ return;
+ }
+ #endregion virtual
+ }
+ ///
+ /// Deals with DataRowView objects
+ ///
+ internal class DataRowViewAdapter : PropertyOnlyAdapter
+ {
+ #region virtual
+ ///
+ /// Retrieves all the properties available in the object.
+ ///
+ /// object to get all the property information from
+ /// collection where the members will be added
+ protected override void DoAddAllProperties(object obj, PSMemberInfoInternalCollection members)
+ {
+ DataRowView dataRowView = (DataRowView)obj;
+ if (dataRowView.Row == null || dataRowView.Row.Table == null || dataRowView.Row.Table.Columns == null)
+ {
+ return;
+ }
+
+ foreach (DataColumn property in dataRowView.Row.Table.Columns)
+ {
+ members.Add(new PSProperty(property.ColumnName, this, obj, property.ColumnName) as T);
+ }
+
+ return;
+ }
+ ///
+ /// Returns null if propertyName is not a property in the adapter or
+ /// the corresponding PSProperty with its adapterData set to information
+ /// to be used when retrieving the property.
+ ///
+ /// object to retrieve the PSProperty from
+ /// name of the property to be retrieved
+ /// The PSProperty corresponding to propertyName from obj
+ protected override PSProperty DoGetProperty(object obj, string propertyName)
+ {
+ DataRowView dataRowView = (DataRowView)obj;
+
+ if (!dataRowView.Row.Table.Columns.Contains(propertyName))
+ {
+ return null;
+ }
+ string columnName = dataRowView.Row.Table.Columns[propertyName].ColumnName;
+ return new PSProperty(columnName, this, obj, columnName);
+ }
+
+ ///
+ /// Returns the name of the type corresponding to the property
+ ///
+ /// PSProperty obtained in a previous DoGetProperty
+ /// True if the result is for display purposes only
+ /// the name of the type corresponding to the property
+ protected override string PropertyType(PSProperty property, bool forDisplay)
+ {
+ string columnName = (string)property.adapterData;
+ DataRowView dataRowView = (DataRowView)property.baseObject;
+ var dataType = dataRowView.Row.Table.Columns[columnName].DataType;
+ return forDisplay ? ToStringCodeMethods.Type(dataType) : dataType.FullName;
+ }
+
+ ///
+ /// Returns true if the property is settable
+ ///
+ /// property to check
+ /// true if the property is settable
+ protected override bool PropertyIsSettable(PSProperty property)
+ {
+ string columnName = (string)property.adapterData;
+ DataRowView dataRowView = (DataRowView)property.baseObject;
+ return !dataRowView.Row.Table.Columns[columnName].ReadOnly;
+ }
+
+ ///
+ /// Returns true if the property is gettable
+ ///
+ /// property to check
+ /// true if the property is gettable
+ protected override bool PropertyIsGettable(PSProperty property)
+ {
+ return true;
+ }
+
+ ///
+ /// Returns the value from a property coming from a previous call to DoGetProperty
+ ///
+ /// PSProperty coming from a previous call to DoGetProperty
+ /// The value of the property
+ protected override object PropertyGet(PSProperty property)
+ {
+ DataRowView dataRowView = (DataRowView)property.baseObject;
+ return dataRowView[(string)property.adapterData];
+ }
+ ///
+ /// Sets the value of a property coming from a previous call to DoGetProperty
+ ///
+ /// PSProperty coming from a previous call to DoGetProperty
+ /// value to set the property with
+ /// instructs the adapter to convert before setting, if the adapter supports conversion
+ protected override void PropertySet(PSProperty property, object setValue, bool convertIfPossible)
+ {
+ DataRowView dataRowView = (DataRowView)property.baseObject;
+ dataRowView[(string)property.adapterData] = setValue;
+ return;
+ }
+ #endregion virtual
+ }
+
internal class TypeInference
{
[TraceSource("ETS", "Extended Type System")]
diff --git a/src/System.Management.Automation/engine/ExtraAdapter.cs b/src/System.Management.Automation/engine/ExtraAdapter.cs
index 7ef258808d6..c2ca2317e59 100644
--- a/src/System.Management.Automation/engine/ExtraAdapter.cs
+++ b/src/System.Management.Automation/engine/ExtraAdapter.cs
@@ -4,7 +4,6 @@
using System.Collections;
using System.Collections.Generic;
-using System.Data;
using System.DirectoryServices;
using System.Reflection;
using System.Runtime.InteropServices;
@@ -15,220 +14,6 @@
namespace System.Management.Automation
{
- ///
- /// Deals with DataRow objects
- ///
- internal class DataRowAdapter : PropertyOnlyAdapter
- {
- #region virtual
- ///
- /// Retrieves all the properties available in the object.
- ///
- /// object to get all the property information from
- /// collection where the members will be added
- protected override void DoAddAllProperties(object obj, PSMemberInfoInternalCollection members)
- {
- DataRow dataRow = (DataRow)obj;
- if (dataRow.Table == null || dataRow.Table.Columns == null)
- {
- return;
- }
-
- foreach (DataColumn property in dataRow.Table.Columns)
- {
- members.Add(new PSProperty(property.ColumnName, this, obj, property.ColumnName) as T);
- }
-
- return;
- }
- ///
- /// Returns null if propertyName is not a property in the adapter or
- /// the corresponding PSProperty with its adapterData set to information
- /// to be used when retrieving the property.
- ///
- /// object to retrieve the PSProperty from
- /// name of the property to be retrieved
- /// The PSProperty corresponding to propertyName from obj
- protected override PSProperty DoGetProperty(object obj, string propertyName)
- {
- DataRow dataRow = (DataRow)obj;
-
- if (!dataRow.Table.Columns.Contains(propertyName))
- {
- return null;
- }
-
- string columnName = dataRow.Table.Columns[propertyName].ColumnName;
- return new PSProperty(columnName, this, obj, columnName);
- }
-
- ///
- /// Returns the name of the type corresponding to the property
- ///
- /// PSProperty obtained in a previous DoGetProperty
- /// True if the result is for display purposes only
- /// the name of the type corresponding to the property
- protected override string PropertyType(PSProperty property, bool forDisplay)
- {
- string columnName = (string)property.adapterData;
- DataRow dataRow = (DataRow)property.baseObject;
- var dataType = dataRow.Table.Columns[columnName].DataType;
- return forDisplay ? ToStringCodeMethods.Type(dataType) : dataType.FullName;
- }
-
- ///
- /// Returns true if the property is settable
- ///
- /// property to check
- /// true if the property is settable
- protected override bool PropertyIsSettable(PSProperty property)
- {
- string columnName = (string)property.adapterData;
- DataRow dataRow = (DataRow)property.baseObject;
- return !dataRow.Table.Columns[columnName].ReadOnly;
- }
-
- ///
- /// Returns true if the property is gettable
- ///
- /// property to check
- /// true if the property is gettable
- protected override bool PropertyIsGettable(PSProperty property)
- {
- return true;
- }
-
-
- ///
- /// Returns the value from a property coming from a previous call to DoGetProperty
- ///
- /// PSProperty coming from a previous call to DoGetProperty
- /// The value of the property
- protected override object PropertyGet(PSProperty property)
- {
- DataRow dataRow = (DataRow)property.baseObject;
- return dataRow[(string)property.adapterData];
- }
- ///
- /// Sets the value of a property coming from a previous call to DoGetProperty
- ///
- /// PSProperty coming from a previous call to DoGetProperty
- /// value to set the property with
- /// instructs the adapter to convert before setting, if the adapter supports conversion
- protected override void PropertySet(PSProperty property, object setValue, bool convertIfPossible)
- {
- DataRow dataRow = (DataRow)property.baseObject;
- dataRow[(string)property.adapterData] = setValue;
- return;
- }
- #endregion virtual
- }
- ///
- /// Deals with DataRowView objects
- ///
- internal class DataRowViewAdapter : PropertyOnlyAdapter
- {
- #region virtual
- ///
- /// Retrieves all the properties available in the object.
- ///
- /// object to get all the property information from
- /// collection where the members will be added
- protected override void DoAddAllProperties(object obj, PSMemberInfoInternalCollection members)
- {
- DataRowView dataRowView = (DataRowView)obj;
- if (dataRowView.Row == null || dataRowView.Row.Table == null || dataRowView.Row.Table.Columns == null)
- {
- return;
- }
-
- foreach (DataColumn property in dataRowView.Row.Table.Columns)
- {
- members.Add(new PSProperty(property.ColumnName, this, obj, property.ColumnName) as T);
- }
-
- return;
- }
- ///
- /// Returns null if propertyName is not a property in the adapter or
- /// the corresponding PSProperty with its adapterData set to information
- /// to be used when retrieving the property.
- ///
- /// object to retrieve the PSProperty from
- /// name of the property to be retrieved
- /// The PSProperty corresponding to propertyName from obj
- protected override PSProperty DoGetProperty(object obj, string propertyName)
- {
- DataRowView dataRowView = (DataRowView)obj;
-
- if (!dataRowView.Row.Table.Columns.Contains(propertyName))
- {
- return null;
- }
- string columnName = dataRowView.Row.Table.Columns[propertyName].ColumnName;
- return new PSProperty(columnName, this, obj, columnName);
- }
-
- ///
- /// Returns the name of the type corresponding to the property
- ///
- /// PSProperty obtained in a previous DoGetProperty
- /// True if the result is for display purposes only
- /// the name of the type corresponding to the property
- protected override string PropertyType(PSProperty property, bool forDisplay)
- {
- string columnName = (string)property.adapterData;
- DataRowView dataRowView = (DataRowView)property.baseObject;
- var dataType = dataRowView.Row.Table.Columns[columnName].DataType;
- return forDisplay ? ToStringCodeMethods.Type(dataType) : dataType.FullName;
- }
-
- ///
- /// Returns true if the property is settable
- ///
- /// property to check
- /// true if the property is settable
- protected override bool PropertyIsSettable(PSProperty property)
- {
- string columnName = (string)property.adapterData;
- DataRowView dataRowView = (DataRowView)property.baseObject;
- return !dataRowView.Row.Table.Columns[columnName].ReadOnly;
- }
-
- ///
- /// Returns true if the property is gettable
- ///
- /// property to check
- /// true if the property is gettable
- protected override bool PropertyIsGettable(PSProperty property)
- {
- return true;
- }
-
- ///
- /// Returns the value from a property coming from a previous call to DoGetProperty
- ///
- /// PSProperty coming from a previous call to DoGetProperty
- /// The value of the property
- protected override object PropertyGet(PSProperty property)
- {
- DataRowView dataRowView = (DataRowView)property.baseObject;
- return dataRowView[(string)property.adapterData];
- }
- ///
- /// Sets the value of a property coming from a previous call to DoGetProperty
- ///
- /// PSProperty coming from a previous call to DoGetProperty
- /// value to set the property with
- /// instructs the adapter to convert before setting, if the adapter supports conversion
- protected override void PropertySet(PSProperty property, object setValue, bool convertIfPossible)
- {
- DataRowView dataRowView = (DataRowView)property.baseObject;
- dataRowView[(string)property.adapterData] = setValue;
- return;
- }
- #endregion virtual
- }
///
/// Deals with DirectoryEntry objects
///
diff --git a/src/System.Management.Automation/engine/MshObject.cs b/src/System.Management.Automation/engine/MshObject.cs
index 197bdd4c7b4..6dd16ab05bd 100644
--- a/src/System.Management.Automation/engine/MshObject.cs
+++ b/src/System.Management.Automation/engine/MshObject.cs
@@ -381,13 +381,13 @@ private void CommonInitialization(object obj)
new Microsoft.PowerShell.Cim.CimInstanceAdapter()),
PSObject.dotNetInstanceAdapter);
-#if !CORECLR // WMIv1/ADSI/DataRow/DataRowView Adapters Not Supported On CSS
+#if !CORECLR // WMIv1/ADSI Adapters Not Supported in PowerShell Core
private static readonly AdapterSet managementObjectAdapter = new AdapterSet(new ManagementObjectAdapter(), dotNetInstanceAdapter);
private static readonly AdapterSet managementClassAdapter = new AdapterSet(new ManagementClassApdapter(), dotNetInstanceAdapter);
private static readonly AdapterSet directoryEntryAdapter = new AdapterSet(new DirectoryEntryAdapter(), dotNetInstanceAdapter);
+#endif
private static readonly AdapterSet dataRowViewAdapter = new AdapterSet(new DataRowViewAdapter(), s_baseAdapterForAdaptedObjects);
private static readonly AdapterSet dataRowAdapter = new AdapterSet(new DataRowAdapter(), s_baseAdapterForAdaptedObjects);
-#endif
private static readonly AdapterSet s_xmlNodeAdapter = new AdapterSet(new XmlNodeAdapter(), s_baseAdapterForAdaptedObjects);
#region Adapter Mappings
@@ -412,13 +412,13 @@ private static AdapterSet MappedInternalAdapterSet(object obj)
if (obj is PSObject) { return PSObject.s_mshObjectAdapter; }
if (obj is CimInstance) { return PSObject.s_cimInstanceAdapter; }
-#if !CORECLR // WMIv1/ADSI/DataRow/DataRowView Adapters Not Supported On CSS
+#if !CORECLR // WMIv1/ADSI Adapters Not Supported in PowerShell Core
if (obj is ManagementClass) { return PSObject.managementClassAdapter; }
if (obj is ManagementBaseObject) { return PSObject.managementObjectAdapter; }
if (obj is DirectoryEntry) { return PSObject.directoryEntryAdapter; }
+#endif
if (obj is DataRowView) { return PSObject.dataRowViewAdapter; }
if (obj is DataRow) { return PSObject.dataRowAdapter; }
-#endif
if (obj is XmlNode) { return PSObject.s_xmlNodeAdapter; }
return null;
}
diff --git a/src/System.Management.Automation/engine/runtime/Binding/Binders.cs b/src/System.Management.Automation/engine/runtime/Binding/Binders.cs
index 90fad60525f..2dad4d8ef02 100644
--- a/src/System.Management.Automation/engine/runtime/Binding/Binders.cs
+++ b/src/System.Management.Automation/engine/runtime/Binding/Binders.cs
@@ -554,7 +554,6 @@ public override DynamicMetaObject FallbackConvert(DynamicMetaObject target, Dyna
return (errorSuggestion ?? NullResult(target)).WriteToDebugLog(this);
}
-#if !CORECLR
// In CORECLR System.Data.DataTable does not have the DataRowCollection IEnumerable, so disabling code.
if (targetValue is DataTable)
{
@@ -582,7 +581,6 @@ public override DynamicMetaObject FallbackConvert(DynamicMetaObject target, Dyna
target),
GetRestrictions(target))).WriteToDebugLog(this);
}
-#endif
if (IsComObject(targetValue))
{
diff --git a/test/powershell/engine/ETS/Adapter.Tests.ps1 b/test/powershell/engine/ETS/Adapter.Tests.ps1
index 0762b58d746..8ab621038f0 100644
--- a/test/powershell/engine/ETS/Adapter.Tests.ps1
+++ b/test/powershell/engine/ETS/Adapter.Tests.ps1
@@ -108,3 +108,61 @@ Describe "Adapter XML Tests" -tags "CI" {
}
}
}
+
+Describe "DataRow and DataRowView Adapter tests" -tags "CI" {
+
+ BeforeAll {
+ ## Define the DataTable schema
+ $dataTable = [System.Data.DataTable]::new("inputs")
+ $dataTable.Locale = [cultureinfo]::InvariantCulture
+ $dataTable.Columns.Add("Id", [int]) > $null
+ $dataTable.Columns.Add("FirstName", [string]) > $null
+ $dataTable.Columns.Add("LastName", [string]) > $null
+ $dataTable.Columns.Add("YearsInMS", [int]) > $null
+
+ ## Add data entries
+ $dataTable.Rows.Add(@(1, "joseph", "smith", 15)) > $null
+ $dataTable.Rows.Add(@(2, "paul", "smith", 15)) > $null
+ $dataTable.Rows.Add(@(3, "mary jo", "soe", 5)) > $null
+ $dataTable.Rows.Add(@(4, "edmund`todd `n", "bush", 9)) > $null
+ }
+
+ Context "DataRow Adapter tests" {
+
+ It "Should be able to access data columns" {
+ $row = $dataTable.Rows[0]
+ $row.Id | Should Be 1
+ $row.FirstName | Should Be "joseph"
+ $row.LastName | Should Be "smith"
+ $row.YearsInMS | Should Be 15
+ }
+
+ It "DataTable should be enumerable in PowerShell" {
+ ## Get the third entry in the data table
+ $row = $dataTable | Select-Object -Skip 2 -First 1
+ $row.Id | Should Be 3
+ $row.FirstName | Should Be "mary jo"
+ $row.LastName | Should Be "soe"
+ $row.YearsInMS | Should Be 5
+ }
+ }
+
+ Context "DataRowView Adapter tests" {
+
+ It "Should be able to access data columns" {
+ $rowView = $dataTable.DefaultView[1]
+ $rowView.Id | Should Be 2
+ $rowView.FirstName | Should Be "paul"
+ $rowView.LastName | Should Be "smith"
+ $rowView.YearsInMS | Should Be 15
+ }
+
+ It "DataView should be enumerable" {
+ $rowView = $dataTable.DefaultView | Select-Object -Last 1
+ $rowView.Id | Should Be 4
+ $rowView.FirstName | Should Be "edmund`todd `n"
+ $rowView.LastName | Should Be "bush"
+ $rowView.YearsInMS | Should Be 9
+ }
+ }
+}