nreco / data

Fast DB-independent DAL for .NET Core: abstract queries, SQL commands builder, schema-less data access, POCO mapping (micro-ORM).
https://www.nrecosite.com/dalc_net.aspx
MIT License
184 stars 39 forks source link
crud csharp data-access-layer database dot-net dotnetcore micro-orm orm poco sql-builder sql-generation

NReco.Data

Lightweight high-performance data access components for generating SQL commands, mapping results to strongly typed POCO models or dictionaries, schema-less CRUD-operations with RecordSet.

NuGet Windows x64 Ubuntu
NuGet Release AppVeyor Tests

Quick reference

Class Dependencies Purpose
DbFactory incapsulates DB-specific functions and conventions
DbCommandBuilder IDbFactory composes IDbCommand and SQL text for SELECT/UPDATE/DELETE/INSERT, handles app-level dataviews
DbDataAdapter IDbCommandBuilder, IDbConnection CRUD operations for model, dictionary, DataTable or RecordSet: Insert/Update/Delete/Select. Async versions are supported for all methods.
Query Represents abstract query to database; used as parameter in DbCommandBuilder, DbDataAdapter
RelexParser Parsers query string expression (Relex) into Query structure
RecordSet RecordSet model represents in-memory data records, this is lightweight and efficient replacement for classic DataTable/DataRow
DataReaderResult IDataReader reads data from any data reader implementation and efficiently maps it to models, dictionaries, DataTable or RecordSet

NReco.Data documentation:

How to use

Generic implementation of DbFactory can be used with any ADO.NET connector.

DbFactory initialization for SqlClient:

var dbFactory = new DbFactory(System.Data.SqlClient.SqlClientFactory.Instance) {
    LastInsertIdSelectText = "SELECT @@IDENTITY" };

DbFactory initialization for Mysql:

var dbFactory = new DbFactory(MySql.Data.MySqlClient.MySqlClientFactory.Instance) {
    LastInsertIdSelectText = "SELECT LAST_INSERT_ID()" };

DbFactory initialization for Postgresql:

var dbFactory = new DbFactory(Npgsql.NpgsqlFactory.Instance) {
    LastInsertIdSelectText = "SELECT lastval()" };

DbFactory initialization for Sqlite:

var dbFactory = new DbFactory(Microsoft.Data.Sqlite.SqliteFactory.Instance) {
    LastInsertIdSelectText = "SELECT last_insert_rowid()" };

DbCommandBuilder generates SQL commands by Query:

var dbCmdBuilder = new DbCommandBuilder(dbFactory);
var selectCmd = dbCmdBuilder.GetSelectCommand( 
    new Query("Employees", (QField)"BirthDate" > new QConst(new DateTime(1960,1,1)) ) );
var selectGroupByCmd = dbCmdBuilder.GetSelectCommand( 
    new Query("Employees").Select("company_id", new QAggregateField("avg_age", "AVG", "age") ) );
var insertCmd = dbCmdBuilder.GetInsertCommand(
    "Employees", new { Name = "John Smith", BirthDate = new DateTime(1980,1,1) } );
var deleteCmd = dbCmdBuilder.GetDeleteCommand(
    new Query("Employees", (QField)"Name" == (QConst)"John Smith" ) );

DbDataAdapter - provides simple API for CRUD-operations:

var dbConnection = dbFactory.CreateConnection();
dbConnection.ConnectionString = "<db_connection_string>";
var dbAdapter = new DbDataAdapter(dbConnection, dbCmdBuilder);
// map select results to POCO models
var employeeModelsList = dbAdapter.Select( new Query("Employees") ).ToList<Employee>();
// read select result to dictionary
var employeeDictionary = dbAdapter.Select( 
    new Query("Employees", (QField)"EmployeeID"==(QConst)newEmployee.EmployeeID ).Select("FirstName","LastName") 
  ).ToDictionary();
// update by dictionary
dbAdapter.Update( 
    new Query("Employees", (QField)"EmployeeID"==(QConst)1001 ),
    new Dictionary<string,object>() {
        {"FirstName", "Bruce" },
        {"LastName", "Wayne" }
    });
// insert by model
dbAdapter.Insert( "Employees", new { FirstName = "John", LastName = "Smith" } );  

RecordSet - efficient replacement for DataTable/DataRow with very similar API:

var rs = dbAdapter.Select(new Query("Employees")).ToRecordSet();
rs.SetPrimaryKey("EmployeeID");
foreach (var row in rs) {
    Console.WriteLine("ID={0}", row["EmployeeID"]);
    if ("Canada".Equals(row["Country"]))
        row.Delete();
}
dbAdapter.Update(rs);
var rsReader = new RecordSetReader(rs); // DbDataReader for in-memory rows

Relex - compact relational query expressions:

var relex = @"Employees(BirthDate>""1960-01-01"":datetime)[Name,BirthDate]"
var relexParser = new NReco.Data.Relex.RelexParser();
Query q = relexParser.Parse(relex);

More examples

Who is using this?

NReco.Data is in production use at SeekTable.com and PivotData microservice.

License

Copyright 2016-2023 Vitaliy Fedorchenko and contributors

Distributed under the MIT license