NickX.TinyORM 1.0.0

dotnet add package NickX.TinyORM --version 1.0.0
NuGet\Install-Package NickX.TinyORM -Version 1.0.0
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="NickX.TinyORM" Version="1.0.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add NickX.TinyORM --version 1.0.0
#r "nuget: NickX.TinyORM, 1.0.0"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install NickX.TinyORM as a Cake Addin
#addin nuget:?package=NickX.TinyORM&version=1.0.0

// Install NickX.TinyORM as a Cake Tool
#tool nuget:?package=NickX.TinyORM&version=1.0.0

TinyORM - Simple, lightweight .NET MicroORM for SQL-Server

Features

  • Fluent or Attribute Mapping between classes and SQL tables
  • Generic repository pattern as persistence layer, already implemented
  • Attach to existing databases
  • Database creation based on your mapping & definitions
  • Events for CRUD operations which you can hook into

Dependencies

Super Quick Start

  1. Get your SQL ConnectionString
var conString = "Database=myDatabase;Server=myServer,1433;User Id=myUser;Password=mySuperSecretPassword123"
  1. Define your Mapping via Fluent API
var fluentMapping = new FluentMapping()
    .MapTable<Foo>("tblFoos")
		.MapColumn(c => c.Id, allowsNull: false, length: default, DefaultValues.AutoIncrement)
		.MapColumn(c => c.Firstname, "AnotherNameForYourColumn")
		.MapColumn(c => c.DateCreate, allowsNull: false, length: default, DefaultValues.Timestamp)
		.SetPrimaryKey(c => c.Id)
		.PackUp()
	.MapTable<Bar>()
		.MapColumn(c => c.Id, allowsNull: false, length: default, DefaultValues.AutoIncrement)
		.MapColumn(c => c.FooId, allowsNull: false, length: default, DefaultValues.None);
		.SetPrimaryKey(c => c.Id)
		.AddForeignKey<Foo>(b => b.FooId, f => f.Id)
		.PackUp();
  1. Initialize a Connection Factory
var conFactory = new SqlConnectionFactory(
	connectionString: conString,
	mapping: fluentMapping,
	createDb: true
);
  1. Grab your repositories and start manipulating data
var foos = new SqlRepository<Foo>(conFactory);

var newFoo = new Foo()
{
	Firstname = "Biggus",
	Lastname = "Dickus"
};

int insertedKey = (int)foos.Insert(newFoo);

Simplified Overview

<img src="https://i.ibb.co/h2GwcfD/Tiny-ORM-Simplified-Visualization.png" />

CRUD Operations

All well known CRUD functionality is packed into repositories. You can instantiate a repository for any type that you've mapped via your FluentMapping:

var foos = new SqlRepository<Foo>(sqlConnectionFactory);

Select

var foos = new SqlRepository<Foo>(sqlConnectionFactory);

// Get All
var allFoos = foos.All();

// Get an object by Key
var fooByKey = foos.Single(14);

// Get a single object by condition
var condition = foos.CreateQueryConditionBuilder()
	.Start(f => f.Firstname, QueryOperators.Equals, "Biggus")
	.And(f => f.Lastname, QueryOperators.Equals, "Dickus");
var fooByCondition = foos.Single(condition);

// Get multiple by condition
var condition = foos.CreateQueryConditionBuilder()
	.Start(f => f.DateCreate, QueryOperators.LowerThanOrEquals, DateTime.Now.AddYears(-1))
	.Or(f => f.Status, QueryOperators.Equals, Status.Inactive);
var foosByCondition = foos.Multiple(condition);
	

Insert

var foos = new SqlRepository<Foo>(sqlConnectionFactory);

var newFoo = new Foo()
{
	Firstname = "Incontinentia",
	Lastname = "Buttocks"
};
int insertedId = (int)foos.Insert(newFoo);

Update

var foos = new SqlRepository<Foo>(sqlConnectionFactory);

var existingFoo = foos.Single(14);
existingFoo.Firstname = "AnotherFirstname";

foos.Update(existingFoo);

Delete

var foos = new SqlRepository<Foo>(sqlConnectionFactory);

var condition = foos.CreateQueryConditionBuilder()
	.Start(f => f.Status, QueryOperators.Equals, Status.Inactive);
var toDelete = foos.Single(condition);

foos.Delete(toDelete);

Exists

var foos = new SqlRepository<Foo>(sqlConnectionFactory);

var condition = foos.CreateQueryConditionBuilder()
	.Start(f => f.Status, QueryOperators.Equals, Status.Inactive);
	
if (foos.Exists(condition))
{
	// go on and do stuff
}

Query Condition

Queries often depend on conditions. In order to not need to use any strong typed SQL statements anywhere, repositories provide a QueryConditionBuilder for their mapped Type.

Usage

At this point you can define your conditions via (again) a Fluent API.

var fooRepository = new SqlRepository<Foo>(sqlConnectionFactory);

var condition = foos.CreateQueryConditionBuilder()
	.Start(f => f.Status, QueryOperators.Equals, Status.Inactive);

QueryOperators

Following QueryOperators are available.

public enum QueryOperators
{
	Equals,
	NotEquals,
	Contains,
	NotContains,
	StartsWith,
	NotStartsWith,
	EndsWith,
	NotEndsWith,
	GreaterThan,
	LessThan,
	GreaterThanOrEqual,
	LessThanOrEqual
}

Events

Insert, Update & Delete operations all have events attached to them. They're provided by the repository.

Inserted & Updated will always be the Type you've gotten the repository for

var foos = new SqlRepository<Foo>(conFactory);

// after insert
foos.OnInsert += (sender, inserted) =>
{
	Console.WriteLine("Inserted Foo:");
	Console.WriteLine(inserted);
}

// after update
foos.OnUpdate += (sender, inserted, deleted) => 
{
	Console.WriteLine("Updated Foo:");
	Console.WriteLine(inserted);
	Console.WriteLine("Old Foo:");
	Console.WriteLine(deleted);
}

// after delete
foos.OnDelete += (sender, deleted) =>
{
	Console.WriteLine("Deleted Foo:");
	Console.WriteLine(deleted);
}

Issues, Bugs & Requests

Please consider creating an issue if you encounter any problems, bugs, errors or inconveniences. I will happily continue supporting this project.

Disclaimer

This is a personal project which initially started out as a project for learning purposes. Take this information for whatever you want it to. 😃

Product Compatible and additional computed target framework versions.
.NET net5.0 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
1.0.0 307 12/13/2021

Initial Version