Zonit.Extensions.Databases.SqlServer
1.0.8
dotnet add package Zonit.Extensions.Databases.SqlServer --version 1.0.8
NuGet\Install-Package Zonit.Extensions.Databases.SqlServer -Version 1.0.8
<PackageReference Include="Zonit.Extensions.Databases.SqlServer" Version="1.0.8" />
<PackageVersion Include="Zonit.Extensions.Databases.SqlServer" Version="1.0.8" />
<PackageReference Include="Zonit.Extensions.Databases.SqlServer" />
paket add Zonit.Extensions.Databases.SqlServer --version 1.0.8
#r "nuget: Zonit.Extensions.Databases.SqlServer, 1.0.8"
#addin nuget:?package=Zonit.Extensions.Databases.SqlServer&version=1.0.8
#tool nuget:?package=Zonit.Extensions.Databases.SqlServer&version=1.0.8
Zonit.Extensions.Databases
Zonit.Extensions.Databases is a flexible library for building repositories and handling CRUD operations on databases.
It provides abstractions and interfaces, making it easy to manage database access and to extend your repositories with custom logic, REST API data, or other external sources.
You can use your own repositories and expand them anytime with additional functions, while still keeping your codebase clean and modular.
📦 NuGet Packages
Abstraction
Install-Package Zonit.Extensions.Databases.Abstractions
SQL Server Implementation
Install-Package Zonit.Extensions.Databases.SqlServer
🚀 Features
- Speed up repository work � focus on your logic, not on database �plumbing�.
- Simple abstractions for common CRUD operations.
- Full support for DTO models.
- Built-in support for query building (
Where
,Include
,Select
, paging, ordering, and more). - Plug-and-play: Easily extend repositories with custom methods or external data without touching the extension itself.
💡 New! Extension Methods for External Data
You can easily include properties and data from outside your database, for example, by pulling from an external API or service.
This is useful when your model should have extra fields, computed properties, or needs to include data fetched live (not loaded from your DB).
How it works
- Create an Extension Class implementing
IDatabaseExtension<TModel>
- In this class, implement business logic for fetching or computing the desired data.
using Zonit.Extensions.Databases.Examples.Entities;
namespace Zonit.Extensions.Databases.Examples.Extensions;
public class UserExtension : IDatabaseExtension<UserModel>
{
public async Task<UserModel> InitializeAsync(Guid userId, CancellationToken cancellationToken = default)
{
// Here you can call a REST API or any other data source.
var model = new UserModel {
Id = userId,
Name = "UserName",
};
return await Task.FromResult(model);
}
}
- Reference the extension using
.Extension()
in your repository query chain.
var user = await _userRepository.Extension(x => x.UserExtension).GetByIdAsync(userId);
The .Extension(x => x.UserExtension)
call tells the repository to supply or load the UserExtension
property for your entity.
This can be virtual
, NotMapped
, or simply a property populated on demand.
Use case:
Suppose your Blog
entity has a UserModel? User
property, but you want to always fetch the latest user data from an API instead of the DB.
Simply create an extension and reference it. The fetching, mapping, and attach process is handled by the extension system for you.
📖 Example Usage
Entity Model
public class Blog
{
public Guid Id { get; set; }
[NotMapped]
public UserModel? User { get; set; }
public Guid? UserId { get; set; }
public string Title { get; set; } = string.Empty;
public string Content { get; set; } = string.Empty;
public DateTime Created { get; private set; } = DateTime.UtcNow;
}
DTO Example
internal class BlogDto(Blog x)
{
public string Id { get; set; } = $"Id: {x.Id}";
public string Title { get; set; } = $"Title: {x.Title}";
public string Content { get; set; } = $"Content: {x.Content}";
public string Created { get; set; } = $"Created: {x.Created:G}";
}
public class UserModel
{
public Guid Id { get; set; }
public string Name { get; set; } = string.Empty;
}
Repository Implementation
public interface IBlogRepository : IDatabaseRepository<Blog> { }
internal class BlogRepository(DatabaseContext _context)
: DatabaseRepository<Blog>(_context), IBlogRepository { }
Service Registration / Dependency Injection
builder.Services.AddDbSqlServer<DatabaseContext>();
builder.Services.AddTransient<IBlogRepository, BlogRepository>();
⚙️ CRUD and Query Operations
Create
var blog = await _blogRepository.AddAsync(new Blog
{
Title = "Hello World",
Content = "Example content"
});
Read (Single or DTO)
var blogSingle = await _blogRepository.GetByIdAsync(blogId);
var blogSingleDto = await _blogRepository.GetByIdAsync<BlogDto>(blogId);
Query First (with conditions)
var firstBlog = await _blogRepository.Where(x => x.Title == "Hello World").GetFirstAsync();
var firstBlogDto = await _blogRepository.Where(x => x.Title == "Hello World").GetFirstAsync<BlogDto>();
Update
var updated = await _blogRepository.UpdateAsync(blog.Id, entity =>
{
entity.Title = "New Title";
});
or
blog.Title = "New Title";
var updated = await _blogRepository.UpdateAsync(blog);
Delete
var deleted = await _blogRepository.DeleteAsync(blog.Id);
or
var deleted = await _blogRepository.DeleteAsync(blog);
Read All
var blogs = await _blogRepository.GetListAsync();
var blogsDto = await _blogRepository.GetListAsync<BlogDto>();
📃 Repository APIs
Below is an overview of the main interfaces and methods.
(See XML comments in code for details.)
IDatabaseRepository<TEntity>
// Queryable & CRUD interface for TEntity
IDatabaseAsQueryable<TEntity> AsQuery();
// Query customization:
IDatabaseQueryOperations<TEntity> Extension(Expression<Func<TEntity, object?>> extensionExpression);
IDatabaseQueryOperations<TEntity> Select<TDto>(Expression<Func<TEntity, TDto>> selector);
IDatabaseQueryOperations<TEntity> Include(Expression<Func<TEntity, object?>> includeExpression);
IDatabaseQueryOperations<TEntity> Where(Expression<Func<TEntity, bool>> whereExpression);
IDatabaseMultipleQueryable<TEntity> Skip(int count);
IDatabaseMultipleQueryable<TEntity> Take(int count);
IDatabaseMultipleRepository<TEntity> OrderBy(Expression<Func<TEntity, object>> keySelector);
IDatabaseMultipleRepository<TEntity> OrderByDescending(Expression<Func<TEntity, object>> keySelector);
// Single record access:
Task<TEntity?> GetByIdAsync(int id, CancellationToken cancellationToken = default);
Task<TDto?> GetByIdAsync<TDto>(int id, CancellationToken cancellationToken = default);
Task<TEntity?> GetByIdAsync(Guid id, CancellationToken cancellationToken = default);
Task<TDto?> GetByIdAsync<TDto>(Guid id, CancellationToken cancellationToken = default);
Task<TEntity?> GetAsync(CancellationToken cancellationToken = default);
Task<TDto?> GetAsync<TDto>(CancellationToken cancellationToken = default);
// Existence check:
Task<bool> AnyAsync(CancellationToken cancellationToken = default);
// Add/Update/Delete:
Task<TEntity> AddAsync(TEntity entity, CancellationToken cancellationToken = default);
Task<TDto> AddAsync<TDto>(TEntity entity, CancellationToken cancellationToken = default);
Task<bool> UpdateAsync(int id, Action<TEntity> updateAction, CancellationToken cancellationToken = default);
Task<bool> UpdateAsync(Guid id, Action<TEntity> updateAction, CancellationToken cancellationToken = default);
Task<bool> UpdateAsync(TEntity entity, CancellationToken cancellationToken = default);
Task<bool> DeleteAsync(int entity, CancellationToken cancellationToken = default);
Task<bool> DeleteAsync(Guid entity, CancellationToken cancellationToken = default);
Task<bool> DeleteAsync(TEntity entity, CancellationToken cancellationToken = default);
// Multiple records access:
Task<IReadOnlyCollection<TEntity>?> GetListAsync(CancellationToken cancellationToken = default);
Task<IReadOnlyCollection<TDto>?> GetListAsync<TDto>(CancellationToken cancellationToken = default);
Task<TEntity?> GetFirstAsync(CancellationToken cancellationToken = default);
Task<TDto?> GetFirstAsync<TDto>(CancellationToken cancellationToken = default);
Task<int?> UpdateRangeAsync(Action<TEntity> updateAction, CancellationToken cancellationToken = default);
Task<int> GetCountAsync(CancellationToken cancellationToken = default);
Note:
The deprecated IDatabasesRepository<TEntity>
interface has been removed and is not supported anymore. Please migrate to IDatabaseRepository<TEntity>
and related interfaces for all new development.
🌟 Why use this extension?
- Build repository pattern code faster and cleaner.
- Decouple your database logic from your app logic.
- Easily extend your repositories with custom business logic or fetch data from external APIs with zero changes to the
ℹ️ For more examples
See the Examples
project included in the repository.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. 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 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 is compatible. 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. |
-
net10.0
- Microsoft.EntityFrameworkCore (>= 10.0.0-preview.4.25258.110)
- Microsoft.EntityFrameworkCore.Abstractions (>= 10.0.0-preview.4.25258.110)
- Microsoft.EntityFrameworkCore.SqlServer (>= 10.0.0-preview.4.25258.110)
- Microsoft.Extensions.Hosting (>= 10.0.0-preview.4.25258.110)
- Zonit.Extensions.Databases.Abstractions (>= 1.0.8)
-
net8.0
- Microsoft.EntityFrameworkCore (>= 8.0.16)
- Microsoft.EntityFrameworkCore.Abstractions (>= 8.0.16)
- Microsoft.EntityFrameworkCore.SqlServer (>= 8.0.16)
- Microsoft.Extensions.Hosting (>= 8.0.1)
- Zonit.Extensions.Databases.Abstractions (>= 1.0.8)
-
net9.0
- Microsoft.EntityFrameworkCore (>= 9.0.5)
- Microsoft.EntityFrameworkCore.Abstractions (>= 9.0.5)
- Microsoft.EntityFrameworkCore.SqlServer (>= 9.0.5)
- Microsoft.Extensions.Hosting (>= 9.0.5)
- Zonit.Extensions.Databases.Abstractions (>= 1.0.8)
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.8 | 29 | 5/28/2025 |
1.0.7 | 32 | 5/28/2025 |
1.0.6 | 40 | 5/24/2025 |
1.0.5 | 110 | 5/19/2025 |
1.0.4 | 132 | 5/7/2025 |
1.0.3 | 106 | 4/25/2025 |
1.0.2 | 156 | 4/23/2025 |
1.0.1 | 152 | 4/22/2025 |
1.0.0 | 74 | 4/19/2025 |
0.1.14 | 77 | 4/19/2025 |
0.1.13 | 84 | 4/19/2025 |
0.1.12 | 191 | 4/18/2025 |
0.1.11 | 177 | 4/17/2025 |
0.1.10 | 185 | 4/17/2025 |
0.1.9 | 182 | 4/17/2025 |
0.1.8 | 174 | 4/17/2025 |
0.1.7 | 174 | 4/17/2025 |
0.1.6 | 192 | 4/16/2025 |
0.1.5 | 97 | 1/29/2025 |
0.1.4 | 131 | 6/13/2024 |
0.1.3 | 113 | 6/5/2024 |
0.1.2 | 113 | 6/4/2024 |
0.1.1 | 109 | 6/4/2024 |
0.1.0 | 118 | 6/3/2024 |
0.0.13 | 108 | 5/1/2024 |
0.0.12 | 114 | 4/28/2024 |
0.0.11 | 132 | 4/24/2024 |
0.0.10 | 120 | 4/22/2024 |
0.0.9 | 116 | 4/21/2024 |
0.0.8 | 136 | 4/21/2024 |
0.0.7 | 125 | 4/18/2024 |
0.0.6 | 118 | 4/18/2024 |