Lightweight C# DataTable alternative providing filtering and grouping.
Clone the repository. Use the dotnet build
command to build the projects.
git clone https://github.com/cpersona/Opine.Data.DataTables
cd Opine.Data.DataTables
dotnet build
The original .NET DataSet/DataTable provided a lot of useful functionality, but it came with a heavy price in terms of performance as well as the patterns and practices that formed around the dataset as developers tried to integrate them into their workflows. From a performance standpoint, DataSets were memory intensive, and serializing them across the wire meant high serialization times and large payloads. From a development perspective, DataSets provided too much functionality, eventually luring developers into treating them as domain objects and first class citizens in applications eschewing SOLID principles in the process.
Opine DataTables provide some of the same functionality as the original DataSet datatables without all of the extra functionality that would otherwise leak into the design of clients of the library.
At the core of DataTables is the IDataTable
interface which is primarily an enumerable of IDataRow
as well as providing access to the underlying data and data schema (e.g. column names and indices). IDataRow
similarly provides access to the underlying data and data schema.
The default implementation of IDataTable
is DataTable
which contains a single object array of all the values it contains and column information.
var columns = new string[]
{
"Name", "Age"
};
var values = new object[]
{
"Bob", 55,
"Tom", 32,
"Jim", 43
};
var table = new DataTable(columns, values);
IDataTable
provides an enumeration of the rows contained within as well as random access to rows or to individual data cells within the data.
var table = GetDataTable();
int i = 0;
foreach (var r in table)
{
// All equivalent to "r"
var sameRow = table.GetRow(i);
var alsoSameRow = table.GetRow(r.GetRowIndex());
i++;
}
Filtering is done by providing a list of IRowFilter
instances. Standard comparison filters are provided and custom filters can be created. Of course, LINQ can be used to perform filtering operations if needed. Filtered tables simply contain row indices and a pointer back to their source table making them very lightweight.
var filteredTable = GetDataTable().FilterBy(new IRowFilter[] { new MyCustomFilter(42) }, true);
A ToDataTable
extension method has been added to IEnumerable<IDataRow>
to make working with LINQ collections easier. See the example below or unit tests for a full example.
var rows = GetDataTable().Where(x => (int)x.GetValue("Age") > 40);
var table = rows.ToDataTable();
Grouping is done by providing a list of column names to group by. The result is an IGroupedDataTable
which provides functionality for accessing the rows within a specific group. Data within a grouped table is provided as instances of IGroupedDataRow
which similarly provides access to the grouped rows. As with filtered tables, grouped tables contain row indices and a pointer back to their source table.
var groupedTable = GetDataTable().GroupBy(new[] { "Age" });
Serialization of a DataTable is simple given the internal structure of the default DataTable which consists of an object array and limited column metadata.
Yes! This project is under the Opine project, but does not have code dependencies on Opine. Therefore, you can use this project anywhere with a simple reference.
- .NET Core 2.0
- C# 7
- N/A
- N/A
- N/A
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.