![]() |
VOOZH | about |
dotnet add package DKNet.EfCore.Repos.Abstractions --version 9.5.39
NuGet\Install-Package DKNet.EfCore.Repos.Abstractions -Version 9.5.39
<PackageReference Include="DKNet.EfCore.Repos.Abstractions" Version="9.5.39" />
<PackageVersion Include="DKNet.EfCore.Repos.Abstractions" Version="9.5.39" />Directory.Packages.props
<PackageReference Include="DKNet.EfCore.Repos.Abstractions" />Project file
paket add DKNet.EfCore.Repos.Abstractions --version 9.5.39
#r "nuget: DKNet.EfCore.Repos.Abstractions, 9.5.39"
#:package DKNet.EfCore.Repos.Abstractions@9.5.39
#addin nuget:?package=DKNet.EfCore.Repos.Abstractions&version=9.5.39Install as a Cake Addin
#tool nuget:?package=DKNet.EfCore.Repos.Abstractions&version=9.5.39Install as a Cake Tool
👁 NuGet
👁 NuGet Downloads
👁 .NET
Repository pattern abstractions for Entity Framework Core, providing clean separation between read and write operations with strongly-typed interfaces. This package defines the contracts for data access operations following CQRS principles and Domain-Driven Design patterns.
Install via NuGet Package Manager:
dotnet add package DKNet.EfCore.Repos.Abstractions
Or via Package Manager Console:
Install-Package DKNet.EfCore.Repos.Abstractions
using DKNet.EfCore.Repos.Abstractions;
// Domain entity
public class Product : Entity<Guid>
{
public string Name { get; set; }
public decimal Price { get; set; }
public string Category { get; set; }
}
// Custom repository interface
public interface IProductRepository : IRepository<Product>
{
Task<IEnumerable<Product>> GetProductsByCategoryAsync(string category, CancellationToken cancellationToken = default);
Task<bool> ExistsByNameAsync(string name, CancellationToken cancellationToken = default);
}
// Service using repository
public class ProductService
{
private readonly IProductRepository _productRepository;
public ProductService(IProductRepository productRepository)
{
_productRepository = productRepository;
}
public async Task<Product> CreateProductAsync(string name, decimal price, string category)
{
// Check if product already exists
if (await _productRepository.ExistsByNameAsync(name))
throw new InvalidOperationException($"Product with name '{name}' already exists");
var product = new Product
{
Name = name,
Price = price,
Category = category
};
await _productRepository.AddAsync(product);
await _productRepository.SaveChangesAsync();
return product;
}
}
public class ProductQueryService
{
private readonly IReadRepository<Product> _readRepository;
public ProductQueryService(IReadRepository<Product> readRepository)
{
_readRepository = readRepository;
}
public async Task<List<ProductDto>> GetActiveProductsAsync()
{
// Use projection for efficient queries
return await _readRepository
.GetDto<ProductDto>(p => p.IsActive)
.OrderBy(p => p.Name)
.ToListAsync();
}
public async Task<Product?> GetProductByIdAsync(Guid id)
{
return await _readRepository.FindAsync(id);
}
public IQueryable<Product> GetProductsQuery()
{
// Return IQueryable for complex filtering
return _readRepository.Gets();
}
}
public class ProductDto
{
public Guid Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public string Category { get; set; }
}
public class ProductManagementService
{
private readonly IWriteRepository<Product> _writeRepository;
public ProductManagementService(IWriteRepository<Product> writeRepository)
{
_writeRepository = writeRepository;
}
public async Task BulkUpdatePricesAsync(List<ProductPriceUpdate> updates)
{
using var transaction = await _writeRepository.BeginTransactionAsync();
try
{
foreach (var update in updates)
{
var product = await _writeRepository.FindAsync(update.ProductId);
if (product != null)
{
product.Price = update.NewPrice;
await _writeRepository.UpdateAsync(product);
}
}
await _writeRepository.SaveChangesAsync();
await transaction.CommitAsync();
}
catch
{
await transaction.RollbackAsync();
throw;
}
}
public async Task AddProductsInBatchAsync(List<Product> products)
{
await _writeRepository.AddRangeAsync(products);
await _writeRepository.SaveChangesAsync();
}
}
public class ProductPriceUpdate
{
public Guid ProductId { get; set; }
public decimal NewPrice { get; set; }
}
using Microsoft.Extensions.DependencyInjection;
using DKNet.EfCore.Repos.Abstractions;
// Register repositories in DI container
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddRepositories(this IServiceCollection services)
{
// Register read-only repositories
services.AddScoped<IReadRepository<Product>, ProductReadRepository>();
services.AddScoped<IReadRepository<Customer>, CustomerReadRepository>();
// Register write repositories
services.AddScoped<IWriteRepository<Product>, ProductWriteRepository>();
services.AddScoped<IWriteRepository<Customer>, CustomerWriteRepository>();
// Register full repositories
services.AddScoped<IRepository<Product>, ProductRepository>();
services.AddScoped<IRepository<Customer>, CustomerRepository>();
// Register custom repositories
services.AddScoped<IProductRepository, ProductRepository>();
services.AddScoped<ICustomerRepository, CustomerRepository>();
return services;
}
}
IRepository<TEntity> - Combined read and write operationsIReadRepository<TEntity> - Read-only operations and queriesIWriteRepository<TEntity> - Write operations and transaction managementGets() - Get IQueryable for entityGetDto<TModel>(Expression<Func<TEntity, bool>>?) - Get projection with optional filterFindAsync(object, CancellationToken) - Find entity by primary keyFindAsync(object[], CancellationToken) - Find entity by composite keyAnyAsync(Expression<Func<TEntity, bool>>, CancellationToken) - Check if any entity matches conditionCountAsync(Expression<Func<TEntity, bool>>, CancellationToken) - Count entities matching conditionAddAsync(TEntity, CancellationToken) - Add single entityAddRangeAsync(IEnumerable<TEntity>, CancellationToken) - Add multiple entitiesUpdateAsync(TEntity, CancellationToken) - Update single entityUpdateRangeAsync(IEnumerable<TEntity>, CancellationToken) - Update multiple entitiesDeleteAsync(TEntity, CancellationToken) - Delete single entityDeleteRangeAsync(IEnumerable<TEntity>, CancellationToken) - Delete multiple entitiesSaveChangesAsync(CancellationToken) - Persist changes to databaseBeginTransactionAsync(CancellationToken) - Begin database transactionEntry(TEntity) - Get EntityEntry for change trackingpublic interface IOrderRepository : IRepository<Order>
{
Task<IEnumerable<Order>> GetOrdersByStatusAsync(OrderStatus status, CancellationToken cancellationToken = default);
Task<Order?> GetOrderWithItemsAsync(Guid orderId, CancellationToken cancellationToken = default);
Task<decimal> GetTotalSalesAsync(DateTime fromDate, DateTime toDate, CancellationToken cancellationToken = default);
}
public class OrderService
{
private readonly IOrderRepository _orderRepository;
private readonly IProductRepository _productRepository;
public OrderService(IOrderRepository orderRepository, IProductRepository productRepository)
{
_orderRepository = orderRepository;
_productRepository = productRepository;
}
public async Task<Order> CreateOrderAsync(Guid customerId, List<OrderItemRequest> items)
{
using var transaction = await _orderRepository.BeginTransactionAsync();
try
{
var order = new Order(customerId);
// Validate and add items
foreach (var item in items)
{
var product = await _productRepository.FindAsync(item.ProductId);
if (product == null)
throw new InvalidOperationException($"Product {item.ProductId} not found");
order.AddItem(item.ProductId, item.Quantity, product.Price);
}
await _orderRepository.AddAsync(order);
await _orderRepository.SaveChangesAsync();
await transaction.CommitAsync();
return order;
}
catch
{
await transaction.RollbackAsync();
throw;
}
}
}
public class ProductSpecificationService
{
private readonly IReadRepository<Product> _readRepository;
public ProductSpecificationService(IReadRepository<Product> readRepository)
{
_readRepository = readRepository;
}
public async Task<List<Product>> GetProductsAsync(ProductSearchCriteria criteria)
{
var query = _readRepository.Gets();
if (!string.IsNullOrEmpty(criteria.Category))
query = query.Where(p => p.Category == criteria.Category);
if (criteria.MinPrice.HasValue)
query = query.Where(p => p.Price >= criteria.MinPrice.Value);
if (criteria.MaxPrice.HasValue)
query = query.Where(p => p.Price <= criteria.MaxPrice.Value);
if (!string.IsNullOrEmpty(criteria.SearchTerm))
query = query.Where(p => p.Name.Contains(criteria.SearchTerm));
return await query
.OrderBy(p => p.Name)
.Skip(criteria.Skip)
.Take(criteria.Take)
.ToListAsync();
}
}
public class ProductSearchCriteria
{
public string? Category { get; set; }
public decimal? MinPrice { get; set; }
public decimal? MaxPrice { get; set; }
public string? SearchTerm { get; set; }
public int Skip { get; set; } = 0;
public int Take { get; set; } = 50;
}
public interface IUnitOfWork
{
IProductRepository Products { get; }
ICustomerRepository Customers { get; }
IOrderRepository Orders { get; }
Task<int> SaveChangesAsync(CancellationToken cancellationToken = default);
Task<IDbContextTransaction> BeginTransactionAsync(CancellationToken cancellationToken = default);
}
public class BusinessService
{
private readonly IUnitOfWork _unitOfWork;
public BusinessService(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public async Task ProcessOrderAsync(OrderRequest request)
{
using var transaction = await _unitOfWork.BeginTransactionAsync();
try
{
// Create customer if not exists
var customer = await _unitOfWork.Customers.FindAsync(request.CustomerId);
if (customer == null)
{
customer = new Customer(request.CustomerEmail);
await _unitOfWork.Customers.AddAsync(customer);
}
// Create order
var order = new Order(customer.Id);
await _unitOfWork.Orders.AddAsync(order);
// Update product inventory
foreach (var item in request.Items)
{
var product = await _unitOfWork.Products.FindAsync(item.ProductId);
if (product != null)
{
product.ReduceInventory(item.Quantity);
await _unitOfWork.Products.UpdateAsync(product);
}
}
await _unitOfWork.SaveChangesAsync();
await transaction.CommitAsync();
}
catch
{
await transaction.RollbackAsync();
throw;
}
}
}
GetDto<T>() for efficient queries that only select needed columnsSee the main for guidelines on how to contribute to this project.
This project is licensed under the .
Part of the DKNet Framework - A comprehensive .NET framework for building modern, scalable applications.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 net9.0 is compatible. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 was computed. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
Showing the top 1 NuGet packages that depend on DKNet.EfCore.Repos.Abstractions:
| Package | Downloads |
|---|---|
|
DKNet.EfCore.Repos
Package Description |
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 9.5.39 | 463 | 11/13/2025 |
| 9.5.38 | 291 | 11/6/2025 |
| 9.5.37 | 269 | 11/5/2025 |
| 9.5.36 | 279 | 11/5/2025 |
| 9.5.35 | 266 | 11/4/2025 |
| 9.5.34 | 264 | 11/4/2025 |
| 9.5.33 | 268 | 11/3/2025 |
| 9.5.32 | 258 | 11/3/2025 |
| 9.5.31 | 246 | 10/31/2025 |
| 9.5.30 | 257 | 10/31/2025 |
| 9.5.29 | 278 | 10/30/2025 |
| 9.5.28 | 257 | 10/27/2025 |
| 9.5.27 | 276 | 10/27/2025 |
| 9.5.26 | 253 | 10/27/2025 |
| 9.5.25 | 237 | 10/26/2025 |
| 9.5.24 | 197 | 10/25/2025 |
| 9.5.23 | 189 | 10/25/2025 |
| 9.5.22 | 188 | 10/25/2025 |
| 9.5.21 | 262 | 10/24/2025 |
| 9.5.20 | 273 | 10/23/2025 |