Linka 1.0.1
dotnet add package Linka --version 1.0.1
NuGet\Install-Package Linka -Version 1.0.1
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="Linka" Version="1.0.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Linka" Version="1.0.1" />
<PackageReference Include="Linka" />
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Linka --version 1.0.1
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Linka, 1.0.1"
#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.
#:package Linka@1.0.1
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Linka&version=1.0.1
#tool nuget:?package=Linka&version=1.0.1
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
Linka ORM
A modern, type-safe Object-Relational Mapping (ORM) framework for .NET with PostgreSQL, designed for high performance and developer productivity.
Features
- ๐ Type-Safe: Strongly typed models with compile-time validation
- ๐ฏ Field-Based Architecture: Rich field types with built-in validation
- ๐ Change Tracking: Automatic detection of field modifications
- ๐งช Testing Framework: Built-in test utilities with database mocking
- ๐ Query Builder: Fluent API for complex database operations
- ๐ Schema Management: Automatic database schema generation and migration
- ๐ Validation: Comprehensive field validation with custom validators
- ๐จ Flexible: Support for enums, custom types, and complex relationships
Quick Start
1. Define Your Models
public class UserModel() : Model
{
[Key]
[Unique]
[FullText]
public IdDbField ID { get; } = new();
[FullText]
public NameDbField Name { get; } = new();
[FullText]
[Unique]
public EmailDbField Email { get; } = new();
[FullText]
public PhoneDbField Phone { get; } = new();
public enum RankEnum
{
User,
Admin
}
public EnumDbField<RankEnum> Rank { get; } = new();
[Unique]
[NotRequired]
public HashDbField Session { get; } = new();
public TextDbField Password { get; } = new();
[NotRequired] // Navigation Field Property
public IdDbField CartToken { get; } = new();
public DateDbField Created { get; } = new();
public BooleanDbField Verified { get; } = new();
public BooleanDbField Login { get; } = new();
public PriceDbField<Gbp> Credit { get; } = new();
[PkNavigationList(nameof(IpAddressModel.UserID))]
public List<IpAddressModel> IpAddresses = null!;
public UserModel(
string name,
string email,
string phone,
RankEnum rankEnum,
string password,
string? cartToken,
bool verified,
bool login,
int credit
) : this()
{
Name.Value(name);
Email.Value(email);
Phone.Value(phone);
Rank.Value(rankEnum);
Password.Value(password);
CartToken.Value(cartToken);
Created.SetNow();
Verified.Value(verified);
Login.Value(login);
Credit.Value(credit);
}
}
2. Create Database Schema
[method: Enum<UserModel.RankEnum>]
[method: Model<UserModel>]
[method: Model<IpAddressModel>]
public class UserSchema() : Schema("User");
3. Basic Operations
// Create a new user using constructor
var model1 = new UserModel(
"John",
"johndoe@example.com",
"1234567890",
UserModel.RankEnum.User,
"password",
null,
true,
false,
100
);
model1.ID.Value("AAAAAAAAAA");
// Insert into database
using var db = new DbService<UserSchema>();
db.Insert(model1);
db.SaveChanges();
// Query single user
var user = db.Get<UserModel>(u => u.ID == "AAAAAAAAAA");
var userOrNull = db.GetOrNull<UserModel>(u => u.ID == "NONEXISTENT");
// Query multiple users
var adminUsers = db.GetMany<UserModel>(u => u.Rank == UserModel.RankEnum.Admin).Load();
var userCount = db.GetMany<UserModel>(u => u.Verified == true).Count();
// Update user fields directly
var foundUser = db.Get<UserModel>(u => u.ID == "AAAAAAAAAA");
foundUser.Name.Value("John Updated");
foundUser.Rank.Value(UserModel.RankEnum.Admin);
// Changes are automatically tracked
// Delete user
db.Delete<UserModel>(u => u.ID == "AAAAAAAAAA");
Database Operations
Querying
using var db = new DbService<UserSchema>();
// Single record queries
var user = db.Get<UserModel>(u => u.Email == "johndoe@example.com");
var userOrNull = db.GetOrNull<UserModel>(u => u.ID == "AAAAAAAAAA");
// Multiple record queries
var getManyExpression = db.GetMany<UserModel>(u => u.Verified == true);
var users = getManyExpression.Load(); // Execute and get results
var count = getManyExpression.Count(); // Get count without loading data
// Complex queries
var adminUsers = db.GetMany<UserModel>(u => u.Rank == UserModel.RankEnum.Admin).Load();
var verifiedUsers = db.GetMany<UserModel>(u => u.Verified == true).Load();
CRUD Operations
using var db = new DbService<UserSchema>();
// Create
var user = new UserModel(
"Alice",
"alice@example.com",
"0987654321",
UserModel.RankEnum.Admin,
"securePass123",
null,
true,
true,
250
);
user.ID.Value("BBBBBBBBBB");
db.Insert(user);
db.SaveChanges();
// Read
var foundUser = db.Get<UserModel>(u => u.ID == "BBBBBBBBBB");
// Update (fields are automatically tracked)
foundUser.Name.Value("Alice Updated");
foundUser.Credit.Value(300);
// Delete
db.Delete<UserModel>(u => u.ID == "BBBBBBBBBB");
Testing
Linka includes a comprehensive testing framework with database mocking:
Test Setup
[Fixtures<UserModelFixture>]
[Fixtures<IpAddressFixture>]
public class UserServiceTests
{
[Test]
public void Get_UserModel_ReturnsExpected()
{
using var db = new DbService<UserSchema>();
var model = db.Get<UserModel>(u => u.ID == "AAAAAAAAAA");
Ensure.Equal("John", model.Name.Value());
}
}
Fixtures
public class UserModelFixture : Fixture<UserSchema>, IFixture
{
public override void Inject()
{
var model1 = new UserModel(
"John",
"johndoe@example.com",
"1234567890",
UserModel.RankEnum.User,
"password",
null,
true,
false,
100
);
model1.ID.Value("AAAAAAAAAA");
using var db = new DbService<UserSchema>();
db.Insert(model1);
db.SaveChanges();
}
}
Multiple Fixtures
[Fixtures<UserModelFixture>]
[Fixtures<IpAddressFixture>]
public class IntegrationTests
{
// All fixtures will be applied before tests run
}
Field Operations
Setting Values
user.Name.Value("John Doe");
user.Created.SetNow(); // Set to current date
user.ID.Value("AAAAAAAAAA"); // Set specific ID
Accessing Values
string name = user.Name.StringValue(); // Get as string
object nameObj = user.Name.ObjectValue(); // Get as typed object
string userName = user.Name.Value(); // Get typed value
Validation
if (user.Email.IsValid(out string message))
{
// Email is valid
}
else
{
Console.WriteLine($"Invalid email: {message}");
}
Best Practices
- Use constructors for creating models with required fields
- Use GetOrNull when records might not exist
- Use GetMany().Count() for counting without loading data
- Use GetMany().Load() when you need the actual records
- Use fixtures for comprehensive test data setup
- Call SaveChanges() after inserts or updates to commit transactions
Requirements
- .NET 9.0 or later
Installation
# Install via NuGet
dotnet add package Linka.ORM
# Or clone and build from source
git clone https://github.com/webamoki/linka-orm.git
cd linka-orm
dotnet build
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net9.0 is compatible. 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. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
net9.0
- Npgsql (>= 9.0.3)
- NUnit (>= 4.4.0)
- Sigil (>= 5.0.0)
- Testcontainers.PostgreSql (>= 4.6.0)
- Webamoki.Utils (>= 1.0.6)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.