![]() |
VOOZH | about |
dotnet add package DataExplorer.EfCore --version 4.1.2
NuGet\Install-Package DataExplorer.EfCore -Version 4.1.2
<PackageReference Include="DataExplorer.EfCore" Version="4.1.2" />
<PackageVersion Include="DataExplorer.EfCore" Version="4.1.2" />Directory.Packages.props
<PackageReference Include="DataExplorer.EfCore" />Project file
paket add DataExplorer.EfCore --version 4.1.2
#r "nuget: DataExplorer.EfCore, 4.1.2"
#:package DataExplorer.EfCore@4.1.2
#addin nuget:?package=DataExplorer.EfCore&version=4.1.2Install as a Cake Addin
#tool nuget:?package=DataExplorer.EfCore&version=4.1.2Install as a Cake Tool
Library featuring a combination of Unit of Work, Repository, Specification and Data Service patterns.
Base DataExplorer package is required.
To register the library services with the DI container use the DataExplorerConfiguration extension method provided by the library:
builder.AddDataExplorer(options =>
{
options.AddEfCore(assembliesToScan);
});
Library provides definition of a base entity (with generic Id and with long Id) which should be inherited by any entity defined within application's domain.
public class CustomEntity : Entity<long>
{
public bool CustomField { get; set; }
}
You can also implement IUpdatedAt and/or ICreatedAt interfaces to let the library handle the metadata properties automatically.
Library supports soft deletion via a IsDisabled property on entities, you can mark an entity as a soft deleted entity using IDisableableEntity interface.
Snowflake IDs are supported using an IdGenerator, to mark an entity to use snowflake IDs inherit from SnowflakeEntity or implement ISnowflakeEntity interface and override the Id property. Ids can be generated by a provided IdGenerator which you can add as a singleton service via AddIdGen()
To avoid LINQ boilerplate a specification pattern is used to encapsulate query logic and should be used like so:
public CustomSpecification : Specification<CustomEntity>
{
public CustomSpecification(bool customField)
{
Where(x => x.CustomField == customField);
}
}
EF 7 ExecuteDeleteAsync and ExecuteUpdateAsync methods are now supported. In order to use the update method you must create a Specification that inherits from UpdateSpecification<TEntitiy>:
public CustomUpdateSpecification : UpdateSpecification<CustomEntity>
{
public CustomUpdateSpecification(bool customField)
{
Where(x => x.CustomField == customField);
Modify(x => x.SetProperty(p => p.CustomField, !customField));
}
}
Please use IntelliSense to check for available methods but pretty much everything should be supported by now.
Every data service automatically grabs it's corresponding entity repository from the Unit of Work and exposes it via properties, you can however do anything and everything through exposed DbContext, UnitOfWork, Mapper and other properties.
Getting a repository is done through methods on IUnitOfWork:
unitOfWork.GetRepository<IRepository<CustomEntity>>();
Please use IntelliSense to find other helpful get repo methods. You can't (without reflection magic) create custom repository implementations, their constructor is internal, you can only get generic repos with the methods exposed via IUnitOfWork, any custom, additional logic, should be performed in the service layer.:
Given below context definitions (always abstract your own context) - either manually register your context interface as a service or use AddDbContext methods on DataExplorerEfCoreConfiguration.
public interface ICustomDbContext : IEfDbContext
{
}
public class CustomDbContext : EfDbContext, ICustomDbContext
{
}
You can define a crud data service like so to add some custom logic:
public interface ICustomDataService : ICrudDataService<CustomEntity, ICustomDbContext>
{
Task<Result> GetFirstEntityWithCustomFieldTrueAndPerformLogicAsync();
}
public class CustomDataService : CrudDataService<CustomEntity, ICustomDbContext>, ICustomDataService
{
public async Task<Result> GetFirstEntityWithCustomFieldTrueAndPerformLogicAsync()
{
var entityRes = await GetSingleBySpecAsync(new CustomSpecification(true));
if (!entityRes.IsDefined(out var entity))
return entityRes;
/// perform custom logic on entity or whatnot
return Result.FromSuccess();
}
}
You can also simply inject a generic data service to perform simple operations like so:
public class CustomController : ControllerBase
{
private readonly IReadOnlyDataService<CustomEntity,ICustomDbContext> _dataService;
public CustomController(IReadOnlyDataService<CustomEntity,ICustomDbContext> dataService)
=> _dataService = dataService;
[HttpGet]
public async Task<IActionResult> GetAllByCustomFieldAsync(bool customField)
{
var subRes = await _dataService.GetBySpecAsync(new CustomSpecification(customField)); // or GetBySpecAsync<SomeDto> to automatically map the entity using AutoMapper
if (!subRes.IsDefined(out var result))
return BadRequest();
return Ok(result);
}
}
All service methods should return a Result struct which determines whether the operation succeeded or not and returns additional objects if necessary and shouldn't throw exceptions unless absolutely necessary.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 net8.0 is compatible. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. 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. |
This package is not used by any NuGet packages.
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 4.1.2 | 297 | 7/3/2025 |
| 4.1.1 | 266 | 7/3/2025 |
| 4.1.0 | 262 | 7/3/2025 |
| 4.0.0 | 291 | 5/26/2025 |
| 3.3.0 | 221 | 5/23/2025 |
| 3.2.1 | 282 | 8/2/2024 |
| 3.2.0 | 242 | 8/2/2024 |
| 3.1.1 | 226 | 7/23/2024 |
| 3.1.0 | 280 | 7/11/2024 |
| 3.0.5 | 339 | 2/16/2024 |
| 3.0.4 | 283 | 1/25/2024 |
| 3.0.3 | 320 | 1/4/2024 |
| 3.0.2 | 312 | 11/22/2023 |
| 3.0.1 | 235 | 11/21/2023 |
| 3.0.0 | 209 | 11/20/2023 |
| 2.3.12 | 267 | 9/12/2023 |
| 2.3.11 | 283 | 9/1/2023 |
| 2.3.10 | 284 | 8/31/2023 |
| 2.3.9 | 277 | 8/31/2023 |
| 2.3.8 | 276 | 8/31/2023 |