Silk.Data.SQL.ORM
0.4.1.1
dotnet add package Silk.Data.SQL.ORM --version 0.4.1.1
NuGet\Install-Package Silk.Data.SQL.ORM -Version 0.4.1.1
<PackageReference Include="Silk.Data.SQL.ORM" Version="0.4.1.1" />
paket add Silk.Data.SQL.ORM --version 0.4.1.1
#r "nuget: Silk.Data.SQL.ORM, 0.4.1.1"
// Install Silk.Data.SQL.ORM as a Cake Addin #addin nuget:?package=Silk.Data.SQL.ORM&version=0.4.1.1 // Install Silk.Data.SQL.ORM as a Cake Tool #tool nuget:?package=Silk.Data.SQL.ORM&version=0.4.1.1
Silk.Data.SQL.ORM
Silk.Data.SQL.ORM
is a .NET library for working with database entities and querying datasets.
It is intended to fill a gap between bigger, more complicated ORMs like EntityFramework/NHibernate and smaller libraries like Dapper - providing a rich query API surface that supports generating obvious SQL queries without the pains of change tracking APIs or lazy-loading from expired data contexts.
Installing
Silk.Data.SQL.ORM
is available as a NuGet package: https://www.nuget.org/packages/Silk.Data.SQL.ORM
You can install it from the NuGet package manager in Visual Studio or from command line with dotnet core:
dotnet add package Silk.Data.SQL.ORM
To run SQL queries against a database you'll also need a DataProvider library: for simplicity you can install Silk.Data.SQL.ProvidersBundle which includes providers for SQLite3, SqlServer, Postgresql and MySQL/MariaDB.
Features
- Type-safe query generation
- Entity and View type mappings
- Full async support
- Minimized round-trips to database servers
- Extensible query functions API
- Embed non-entity types into your schema
- Reference registered entity types with
JOIN
and support querying against referenced entities
Platform Requirements
Silk.Data.SQL.ORM
is built for netstandard2.0.
License
Silk.Data.SQL.ORM
is licensed under the MIT license.
Usage
- Create a schema of entity types
- Create a database provider
- Create tables
- Basic entity queries
- Advanced querying
- Custom database functions
Create a schema of entity types
To query a database first you have to tell Silk.Data.SQL.ORM
the shape of your database. This is done by building a Schema
instance (your application can have multiple schemas if needed) using the SchemaBuilder
API to define your entity types:
var schema = new SchemaBuilder()
.Define<UserAccount>(entityType => {
entityType.Index("idx_loginNameEmailAddr", entity => entity.LoginName, entity => entity.EmailAddress)
})
.Build();
Create a database provider
Creating a database provider isn't actually part of Silk.Data.SQL.ORM
but is specific to which database you'd like to use. Silk.Data.SQL.ProvidersBundle provides 4 major providers:
var dataProvider =
// SQLite3
new SQLite3DataProvider(new Uri("database.db", UriKind.Relative));
// SqlServer
new MSSqlDataProvider(hostname, database, username, password);
// Postgresql
new PostgresqlDataProvider(hostname, database, username, password);
// MySQL/MariaDB
new MySQLDataProvider(hostname, database, username, password);
Create tables
Now that you have a Schema
and a IDataProvider
we can start by creating tables. This is done using the IEntityTable<T>
interface, the standard implementation of which is EntityTable<T>
:
var table = new EntityTable<T>(schema, dataProvider);
await table.Create().ExecuteAsync();
Basic entity queries
Now we have a Schema
, an IDataProvider
and we've created tables in the database provider: we're ready to start working with some entities!
The ISqlEntityStore<T>
interface is what we'll work with for most entity operations. It allows us to work with single entities, query for entity sets and build custom queries as needed.
For now let's insert and query a simple entity set:
var store = new SqlEntityStore<T>(schema, dataProvider);
await new[]
{
store
.Insert(new UserAccount { LoginName = "DevJohnC", EmailAddress = "devjohnc@github.com", CreatedAtUtc = DateTime.UtcNow })
.Defer(),
store
.Select()
.OrderByDescending(account => account.CreatedAtUtc)
.Limit(1)
.Defer(out var queryResult)
}.ExecuteAsync();
Console.WriteLine($"The most recently created user is: {queryResult.Result[0].LoginName}");
This will perform an INSERT
query for your entity, map any generated primary key (currently any integer/guid type Id
property) onto your entity instance and perform a SELECT
for the most recently created user in a single round-trip to the database server.
Advanced querying
But wait, there's more! Silk.Data.SQL.ORM
also boasts some more powerful features:
Transactions
Execute your queries in a transaction using the ExecuteAsTransaction
/ExecuteAsTransactionAsync
extension methods or by creating an instance of Transaction
directly and using it to execute queries:
var transaction = new Transaction();
await transaction.ExecuteAsync(...);
transaction.Commit();
View Expressions
The SELECT
APIs on ISqlEntityStore<T>
support providing an expression to be projected:
var allIDs = store.Select(entity => entity.Id).Execute();
This API currently supports specifying just a single property or database function call. In the future it will support a full anonymous type expression.
View Type Projections
As well as working with full entity types you can SELECT
, INSERT
and DELETE
with view types too. View types use mappings generated by Silk.Data.Modelling:
public class UserAccount
{
// a server-generated, auto-increment primary key
public int Id { get; private set; }
public string DisplayName { get; set; }
}
public class BlogPost
{
public int Id { get; private set; }
public UserAccount Author { get; set; }
}
public class BlogPostAuthorView
{
// mapped and queried from BlogPost.Author.DisplayName
public string AuthorDisplayName { get; set; }
}
var blogPostAuthorsResult = blogPostStore
.Select<BlogPostAuthorView>()
.Execute();
Type Coercion
When providing projections Silk.Data.SQL.ORM
can attempt to transform your data from the datatype it's stored as to the datatype declared on your view.
Type coercions supported:
- Conversion between numeric types
- Conversion to
string
usingToString()
- Conversion from
string
using any resolvedTryParse
method - Conversion using a declared explicit operator
Database Functions
Any API in Silk.Data.SQL.ORM
that accepts an Expression<>
type can include method calls that will be converted in SQL query expressions. By default the methods declared on DatabaseFunctions
and Enum.HasFlag
are supported.
var count = store.Select(
entity => DatabaseFunctions.Count(entity)
)
.AndWhere(
entity => entity.Status.HasFlag(Status.IsPublished)
)
.Single()
.Execute();
Attempting to invoke CLR methods within your Expression
will always be translated to SQL expressions, no runtime method invocations are supported in expressions currently.
Custom database functions
You can provide your own database functions to help with writing complex or repetative SQL expressions for you.
- Write a static method signature on a helper class
- Implement
IMethodCallConverter
- When building a schema call
Schema.AddMethodConverter
with aMethodInfo
instance for your method and theIMethodCallConverter
implementation
Examples of IMethodCallConverter
can be found here: https://github.com/SilkStack/Silk.Data.SQL.ORM/tree/master/Silk.Data.SQL.ORM/Expressions.
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. 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. |
.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
- Silk.Data.Modelling (>= 0.4.0.4)
- Silk.Data.SQL.Base (>= 0.1.2.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.