Skip to content

Commit

Permalink
Add async methods for DbDataAdapter Insert/Update (dictionary/poco) #12
Browse files Browse the repository at this point in the history
  • Loading branch information
VitaliyMF committed Sep 19, 2016
1 parent 089ae0c commit dfe13ab
Show file tree
Hide file tree
Showing 8 changed files with 250 additions and 53 deletions.
16 changes: 11 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
# NReco.Data
Lightweight data access components for generating SQL commands, mapping results to strongly typed POCO models or dictionaries, schema-less CRUD-operations.
Lightweight data access components for generating SQL commands, mapping results to strongly typed POCO models or dictionaries, schema-less CRUD-operations with RecordSet.

* abstract DB-independent [Query structure](https://github.com/nreco/data/wiki/Query) (no need to compose raw SQL)
* DbCommandBuilder for generating SELECT, INSERT, UPDATE and DELETE commands
* DbBatchCommandBuilder for generating several SQL statements into one IDbCommand (batch inserts, updates, multiple recordsets)
* DbBatchCommandBuilder for generating several SQL statements into one IDbCommand (batch inserts, updates, select multiple recordsets)
* [RecordSet model](https://github.com/nreco/data/wiki/RecordSet) for in-memory data records (lightweight and efficient replacement for DataTable/DataRow)
* DbDataAdapter for CRUD-operations, can map query results to POCO models, dictionaries and RecordSet (full async support)
* DbDataAdapter for CRUD-operations:
* supports annotated POCO models (like EF Core entity models)
* schema-less data access API (dictionaries / RecordSet)
* async support for all methods
* application-level data views (complex SQL queries) that accessed like simple read-only tables (DbDataView)
* best for schema-less DB access, dynamic DB queries, user-defined filters, reporting applications
* best for schema-less DB access, dynamic DB queries, user-defined filters; DAL can be used in addition to EF Core
* fills the gap between minimalistic .NET Core (corefx) System.Data and EF Core
* parser/builder for compact string query representation: [relex](https://github.com/nreco/data/wiki/Relex) expressions
* can be used with any existing ADO.NET data provider (MsSql, PostgreSql, Sqlite, MySql etc)
Expand Down Expand Up @@ -54,8 +57,10 @@ dbAdapter.Update(
{"FirstName", "Bruce" },
{"LastName", "Wayne" }
});
// insert by model
dbAdapter.Insert( "Employees", new { FirstName = "John", LastName = "Smith" } );
```
**[RecordSet](https://github.com/nreco/data/wiki/RecordSet)** - efficient replacement for DataTable/DataRow (API is very similar):
**[RecordSet](https://github.com/nreco/data/wiki/RecordSet)** - efficient replacement for DataTable/DataRow with very similar API:
```
var rs = dbAdapter.Select(new Query("Employees")).ToRecordSet();
rs.SetPrimaryKey("EmployeeID");
Expand All @@ -65,6 +70,7 @@ foreach (var row in rs) {
row.Delete();
}
dbAdapter.Update(rs);
var rsReader = new RecordSetReader(rs); // DbDataReader for in-memory rows
```
**[Relex](https://github.com/nreco/data/wiki/Relex)** - compact relational query expressions:
```
Expand Down
50 changes: 50 additions & 0 deletions src/NReco.Data.Tests/DbDataAdapterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,34 @@ public void InsertUpdateDelete_Dictionary() {
Assert.Equal(1, DbAdapter.Delete( norwayCompanyQ ) );
}

[Fact]
public async Task InsertUpdateDelete_DictionaryAsync() {
// insert
DbAdapter.Connection.Open();
Assert.Equal(1,
await DbAdapter.InsertAsync("companies", new Dictionary<string,object>() {
{"title", "Test Inc"},
{"country", "Norway"}
}).ConfigureAwait(false) );
object recordId = DbAdapter.CommandBuilder.DbFactory.GetInsertId(DbAdapter.Connection);
DbAdapter.Connection.Close();

// update
Assert.Equal(1,
await DbAdapter.UpdateAsync( new Query("companies", (QField)"id"==new QConst(recordId) ),
new Dictionary<string,object>() {
{"title", "Megacorp Inc"}
}
).ConfigureAwait(false) );

var norwayCompanyQ = new Query("companies", (QField)"country"==(QConst)"Norway" );

Assert.Equal("Megacorp Inc", DbAdapter.Select(norwayCompanyQ).ToDictionary()["title"]);

// cleanup
Assert.Equal(1, await DbAdapter.DeleteAsync( norwayCompanyQ ).ConfigureAwait(false) );
}

[Fact]
public void InsertUpdateDelete_RecordSet() {

Expand Down Expand Up @@ -209,6 +237,28 @@ public void InsertUpdateDelete_PocoModel() {
Assert.Equal(1, DbAdapter.Delete( newCompany ) );
}

[Fact]
public async Task InsertUpdateDelete_PocoModelAsync() {
// insert
var newCompany = new CompanyModelAnnotated();
newCompany.Id = 5000; // should be ignored
newCompany.Name = "Test Super Corp";
newCompany.registered = false; // should be ignored
Assert.Equal(1, await DbAdapter.InsertAsync(newCompany).ConfigureAwait(false) );

Assert.True(newCompany.Id.HasValue);
Assert.NotEqual(5000, newCompany.Id.Value);

Assert.Equal("Test Super Corp", DbAdapter.Select(new Query("companies", (QField)"id"==(QConst)newCompany.Id.Value).Select("title") ).Single<string>() );

newCompany.Name = "Super Corp updated";
Assert.Equal(1, await DbAdapter.UpdateAsync( newCompany).ConfigureAwait(false) );

Assert.Equal(newCompany.Name, DbAdapter.Select(new Query("companies", (QField)"id"==(QConst)newCompany.Id.Value).Select("title") ).Single<string>() );

Assert.Equal(1, await DbAdapter.DeleteAsync( newCompany ).ConfigureAwait(false) );
}


public class ContactModel {
public int? id { get; set; }
Expand Down
Loading

0 comments on commit dfe13ab

Please sign in to comment.