Net4x.Data.DataSetExtensions 4.8.0.26251

dotnet add package Net4x.Data.DataSetExtensions --version 4.8.0.26251
                    
NuGet\Install-Package Net4x.Data.DataSetExtensions -Version 4.8.0.26251
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Net4x.Data.DataSetExtensions" Version="4.8.0.26251" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Net4x.Data.DataSetExtensions" Version="4.8.0.26251" />
                    
Directory.Packages.props
<PackageReference Include="Net4x.Data.DataSetExtensions" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Net4x.Data.DataSetExtensions --version 4.8.0.26251
                    
#r "nuget: Net4x.Data.DataSetExtensions, 4.8.0.26251"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Net4x.Data.DataSetExtensions@4.8.0.26251
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Net4x.Data.DataSetExtensions&version=4.8.0.26251
                    
Install as a Cake Addin
#tool nuget:?package=Net4x.Data.DataSetExtensions&version=4.8.0.26251
                    
Install as a Cake Tool

Net4x.Data.DataSetExtensions

LINQ to DataSet for .NET Framework 3.5 and 4.0.

System.Data.DataSetExtensions.dll — the assembly that gives you AsEnumerable(), Field<T>(), CopyToDataTable() and the DataRowComparer — only ships with .NET Framework 3.5 SP1 and later, and the types are not available at all in some trimmed or repackaged runtimes. This package provides a drop-in implementation of that API surface under the original System.Data namespace, so code written against LINQ to DataSet compiles and runs unchanged on the older frameworks.

Target frameworks

Target framework What you get
net35, net40 The full implementation, compiled into this assembly.
net45, netstandard2.0 A thin facade that takes a dependency on the official System.Data.DataSetExtensions package, so the framework types are used instead.

Because the types live in the System.Data namespace, multi-targeted projects reference this package once and get the right implementation for every target framework, with no #if in your own code.

Installation

dotnet add package Net4x.Data.DataSetExtensions

or, from the Package Manager Console:

Install-Package Net4x.Data.DataSetExtensions

Usage

Everything lives in System.Data, so an existing using System.Data; is all you need.

Querying a DataTable

using System.Data;
using System.Linq;

DataTable scores = GetScores();

var winners = scores.AsEnumerable()
    .Where(row => row.Field<int>("Score") >= 80)
    .OrderByDescending(row => row.Field<int>("Score"))
    .ThenBy(row => row.Field<string>("Name"))
    .Select(row => new { Name = row.Field<string>("Name"), Score = row.Field<int>("Score") });

Query syntax works as well:

var winners = from row in scores.AsEnumerable()
              where row.Field<int>("Score") >= 80
              orderby row.Field<int>("Score") descending
              select row.Field<string>("Name");

Typed field access

Field<T> unwraps DBNull for you: nullable and reference types come back as null, while a non-nullable value type throws InvalidCastException rather than returning a surprise.

string name  = row.Field<string>("Name");          // null when the column is DBNull
int?   bonus = row.Field<int?>("Bonus");           // null when the column is DBNull
int    score = row.Field<int>("Score");            // InvalidCastException when the column is DBNull

// by index, by DataColumn, and per row version
int original = row.Field<int>("Score", DataRowVersion.Original);
int byIndex  = row.Field<int>(3);
int byColumn = row.Field<int>(scores.Columns["Score"]);

SetField<T> is the mirror image and translates null into DBNull.Value:

row.SetField("Name", "Dorkpuff");
row.SetField<int?>("Bonus", null);   // stores DBNull.Value

Materialising a query back into a DataTable

DataTable winnersTable = scores.AsEnumerable()
    .Where(row => row.Field<int>("Score") >= 80)
    .CopyToDataTable();

// or load into a table you already own
scores.AsEnumerable().CopyToDataTable(existingTable, LoadOption.Upsert);

// with per row error handling
scores.AsEnumerable().CopyToDataTable(existingTable, LoadOption.Upsert, (sender, e) =>
{
    Log(e.Errors);
    e.Continue = true;   // skip the offending row and keep going
});

CopyToDataTable without a target table clones the source schema. An empty sequence throws InvalidOperationException in that case, because there is no schema to infer.

Comparing rows by value

var distinct = scores.AsEnumerable().Distinct(DataRowComparer.Default);
bool same = DataRowComparer.Default.Equals(rowA, rowB);

DataRowComparer compares column values rather than references, and understands one dimensional arrays: two rows holding equal byte[] contents compare equal.

Typed DataSets

Designer generated typed DataSets derive their tables from TypedTableBase<TRow>, which this package provides along with its extension methods:

ScoreTable table = dataSet.Score;

ScoreRow first = table.ElementAtOrDefault(0);          // null instead of throwing
var top = table.Where(r => r.Score >= 80)
               .OrderByDescending(r => r.Score);

API surface

  • DataTableExtensions — AsEnumerable, CopyToDataTable (3 overloads)
  • DataRowExtensions — Field<T> (6 overloads), SetField<T> (3 overloads)
  • DataRowComparer, DataRowComparer<TRow>
  • EnumerableRowCollection, EnumerableRowCollection<TRow>, OrderedEnumerableRowCollection<TRow>
  • EnumerableRowCollectionExtensions — Cast, Where, Select, OrderBy, OrderByDescending, ThenBy, ThenByDescending (each with and without an IComparer<TKey>)
  • TypedTableBase<T>, TypedTableBaseExtensions

Known limitation

DataTableExtensions.AsDataView and EnumerableRowCollection<T>.AsDataView are not implemented on net35 and net40. Everything else in the LINQ to DataSet surface is. Consumers that need a live, bindable DataView over a query result should sort and filter through DataView directly.

Building from source

The library multi-targets net35;net40;net45;netstandard2.0. Building the net35 target requires the full Visual Studio MSBuild, because the .NET SDK's dotnet build cannot run the CLR2 resource generator; the other target frameworks build with dotnet build.

Licence

Copyright © Piero Viano. The assembly is strong named.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net35 is compatible.  net40 is compatible.  net403 was computed.  net45 is compatible.  net451 was computed.  net452 was computed.  net46 was computed.  net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
4.8.0.26251 63 9/10/2026
4.7.0 326 4/4/2025