Donald 1.0.1
See the version list below for details.
dotnet add package Donald --version 1.0.1
NuGet\Install-Package Donald -Version 1.0.1
<PackageReference Include="Donald" Version="1.0.1" />
paket add Donald --version 1.0.1
#r "nuget: Donald, 1.0.1"
// Install Donald as a Cake Addin #addin nuget:?package=Donald&version=1.0.1 // Install Donald as a Cake Tool #tool nuget:?package=Donald&version=1.0.1
Donald
Meet Donald.
If you're a programmer and have used a database, he's impacted your life in a big way.
This library is named after him.
Getting Started
Donald is a well-tested library that aims to make working with ADO.NET a little bit more succinct.
Providing basic functional wrappers for the IDbCommand
methods ExecuteNonQuery()
, ExecuteScalar()
& ExecuteReader()
and a full-suite of IDataReader
extension methods to make retrieving values safer and more direct.
If you came looking for an ORM, this is not your light saber. And may the force be with you.
Install the Donald NuGet package:
PM> Install-Package Donald
Or using the dotnet CLI
dotnet add package Donald
An example using SQL Server
Consider the following model:
type Author =
{
AuthorId : int
FullName : string
}
// Not mandatory, but helpful
static member fromReader (rd : IDataReader) =
{
AuthorId = rd.GetInt32("author_id") // IDataReader extension method
FullName = rd.GetString("full_name") // IDataReader extension method
}
Define a DbConnectionFactory
open System.Data.SqlClient
open Donald
let connectionString =
"Server=MY_SERVER;Database=MyDatabase;Trusted_Connection=True;"
let connectionFactory : DbConnectionFactory =
fun _ -> new SqlConnection(connectionString) :> IDbConnection
Query for multiple strongly-typed results
let findAuthor search =
use conn = createConn connectionFactory
query
"SELECT author_id, full_name
FROM author
WHERE full_name LIKE @search"
[ newParam "search" search ]
Author.fromReader
conn
Query for exactly one strongly-type result
let getAuthor authorId =
use conn = createConn connectionFactory
querySingle // Returns Option<Author>
"SELECT author_id, full_name
FROM author
WHERE author_id = @author_id"
[ newParam "author_id" authorId ]
Author.fromReader
conn
Doing work transactionally
The five main API functions: query
, querySingle
, scalar
, exec
and execMany
, all have transactional sister functions: tranQuery
, tranQuerySingle
, tranScalar
, tranExec
and tranExecMany
.
As opposed to an IDbConnection
, these functions expect an IDbTransaction
as the final paramter.
Execute a statement
let updateAuthor author =
use conn = createConn connectionFactory
use tran = beginTran conn
tranExec // ExecuteNonQuery() within scope of transaction
"UPDATE author
SET full_name = @full_name
WHERE author_id = @author_id"
[
newParam "author_id" author.AuthorId
newParam "full_name" author.FullName
]
tran
commitTran tran // safely commit transaction
Execute a statement many times
let insertAuthors =
use conn = createConn connectionFactory
use tran = beginTran conn
tranExecMany
"INSERT INTO author (full_name) VALUES (@full_name);"
[
[ newParam "full_name" "Bugs Bunny" ]
[ newParam "full_name" "Donald Duck" ]
]
tran
commitTran tran
Execute a statement that returns a value
let insertAuthor fullName =
use conn = createConn connectionFactory
use tran = beginTran conn // Base function's are transaction-oriented
let authorId =
tranScalar // ExecuteScalar() within scope of transaction
"INSERT INTO author (full_name)
VALUES (@full_name);
SELECT SCOPE_IDENTITY();"
[ newParam "full_name" fullName]
Convert.ToInt32 // Any obj -> int function would do here
tran
commitTran tran
authorId
IDataReader
Extension Methods
To make obtaining values from reader more straight-forward, 3 sets of extension methods are available for:
- Get value, automatically defaulted
- Get value as
option<'a>
- Get value as
Nullable<'a>
Assume we have an open IDataReader
and are currently reading a row, the IDataRecord
:
rd.GetString "some_field" // string -> string
rd.GetBoolean "some_field" // string -> bool
rd.GetByte "some_field" // string -> byte
rd.GetChar "some_field" // string -> char
rd.GetDateTime "some_field" // string -> DateTime
rd.GetDecimal "some_field" // string -> Decimal
rd.GetDouble "some_field" // string -> Double
rd.GetFloat "some_field" // string -> float32
rd.GetGuid "some_field" // string -> Guid
rd.GetInt16 "some_field" // string -> int16
rd.GetInt32 "some_field" // string -> int32
rd.GetInt64 "some_field" // string -> int64
rd.GetStringOption "some_field" // string -> string option
rd.GetBooleanOption "some_field" // string -> bool option
rd.GetByteOption "some_field" // string -> byte option
rd.GetCharOption "some_field" // string -> char option
rd.GetDateTimeOption "some_field" // string -> DateTime option
rd.GetDecimalOption "some_field" // string -> Decimal option
rd.GetDoubleOption "some_field" // string -> Double option
rd.GetFloatOption "some_field" // string -> float32 option
rd.GetGuidOption "some_field" // string -> Guid option
rd.GetInt16Option "some_field" // string -> int16 option
rd.GetInt32Option "some_field" // string -> int32 option
rd.GetInt64Option "some_field" // string -> int64 option
rd.GetNullableBoolean "some_field" // string -> Nullable<bool>
rd.GetNullableByte "some_field" // string -> Nullable<byte>
rd.GetNullableChar "some_field" // string -> Nullable<char>
rd.GetNullableDateTime "some_field" // string -> Nullable<DateTime>
rd.GetNullableDecimal "some_field" // string -> Nullable<Decimal>
rd.GetNullableDouble "some_field" // string -> Nullable<Double>
rd.GetNullableFloat "some_field" // string -> Nullable<float32>
rd.GetNullableGuid "some_field" // string -> Nullable<Guid>
rd.GetNullableInt16 "some_field" // string -> Nullable<int16>
rd.GetNullableInt32 "some_field" // string -> Nullable<int32>
rd.GetNullableInt64 "some_field" // string -> Nullable<int64>
Find a bug?
There's an issue for that.
License
Built with ♥ by Pim Brouwers in Toronto, ON. Licensed under Apache License 2.0.
Product | Versions 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. |
.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 | 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. |
-
.NETStandard 2.0
- FSharp.Core (>= 4.7.0)
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 |
---|---|---|
10.1.0 | 2,723 | 3/20/2024 |
10.0.2 | 1,111 | 12/12/2023 |
10.0.1 | 971 | 7/11/2023 |
10.0.0 | 157 | 7/8/2023 |
10.0.0-alpha3 | 186 | 2/11/2023 |
10.0.0-alpha2 | 161 | 2/4/2023 |
10.0.0-alpha1 | 147 | 2/3/2023 |
9.0.1 | 1,338 | 1/11/2023 |
9.0.0 | 319 | 12/23/2022 |
8.0.2 | 16,311 | 11/23/2022 |
8.0.1 | 329 | 11/23/2022 |
8.0.0 | 398 | 11/23/2022 |
7.1.0 | 2,714 | 12/17/2021 |
7.0.0 | 338 | 12/14/2021 |
7.0.0-alpha1 | 275 | 11/1/2021 |
6.2.5 | 637 | 8/4/2021 |
6.2.4 | 389 | 8/4/2021 |
6.2.3 | 396 | 7/30/2021 |
6.2.2 | 472 | 7/27/2021 |
6.2.1 | 364 | 7/27/2021 |
6.2.0 | 581 | 7/26/2021 |
6.1.0 | 480 | 7/6/2021 |
6.1.0-beta3 | 236 | 7/5/2021 |
6.1.0-beta2 | 246 | 7/4/2021 |
6.1.0-beta1 | 350 | 7/4/2021 |
6.0.0 | 432 | 4/11/2021 |
5.1.3 | 428 | 3/29/2021 |
5.1.2 | 453 | 2/27/2021 |
5.1.1 | 464 | 1/23/2021 |
5.0.1 | 1,052 | 12/3/2020 |
5.0.0 | 438 | 12/1/2020 |
5.0.0-alpha3 | 293 | 12/1/2020 |
5.0.0-alpha2 | 270 | 11/30/2020 |
5.0.0-alpha1 | 274 | 11/30/2020 |
4.0.0 | 494 | 11/12/2020 |
3.0.4 | 1,788 | 10/31/2020 |
3.0.3 | 749 | 8/2/2020 |
3.0.2 | 536 | 7/17/2020 |
3.0.1 | 520 | 7/14/2020 |
3.0.0 | 560 | 6/29/2020 |
2.0.2 | 491 | 5/1/2020 |
2.0.1 | 460 | 4/27/2020 |
2.0.0 | 469 | 4/27/2020 |
1.0.6 | 444 | 4/24/2020 |
1.0.4 | 428 | 4/24/2020 |
1.0.3 | 458 | 4/24/2020 |
1.0.2 | 461 | 4/24/2020 |
1.0.1 | 664 | 4/18/2020 |
1.0.0 | 496 | 4/5/2020 |