DataExplorer.EfCore
3.1.1
See the version list below for details.
dotnet add package DataExplorer.EfCore --version 3.1.1
NuGet\Install-Package DataExplorer.EfCore -Version 3.1.1
<PackageReference Include="DataExplorer.EfCore" Version="3.1.1" />
paket add DataExplorer.EfCore --version 3.1.1
#r "nuget: DataExplorer.EfCore, 3.1.1"
// Install DataExplorer.EfCore as a Cake Addin #addin nuget:?package=DataExplorer.EfCore&version=3.1.1 // Install DataExplorer.EfCore as a Cake Tool #tool nuget:?package=DataExplorer.EfCore&version=3.1.1
DataExplorer.EfCore
Library featuring a combination of Unit of Work, Repository, Specification and Data Service patterns.
Installation
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);
});
Description
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 | net6.0 is compatible. 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 is compatible. 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 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. |
-
net6.0
- DataExplorer (>= 3.1.1)
- EFCoreSecondLevelCacheInterceptor (>= 4.6.0)
- Microsoft.EntityFrameworkCore (>= 6.0.25 && <= 7.0.14)
- Microsoft.EntityFrameworkCore.Relational (>= 6.0.25 && <= 7.0.14)
-
net7.0
- DataExplorer (>= 3.1.1)
- EFCoreSecondLevelCacheInterceptor (>= 4.6.0)
- Microsoft.EntityFrameworkCore (>= 7.0.14)
- Microsoft.EntityFrameworkCore.Relational (>= 7.0.14)
-
net8.0
- DataExplorer (>= 3.1.1)
- EFCoreSecondLevelCacheInterceptor (>= 4.6.0)
- Microsoft.EntityFrameworkCore (>= 8.0.7)
- Microsoft.EntityFrameworkCore.Relational (>= 8.0.7)
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 |
---|---|---|
3.2.1 | 105 | 8/2/2024 |
3.2.0 | 91 | 8/2/2024 |
3.1.1 | 70 | 7/23/2024 |
3.1.0 | 128 | 7/11/2024 |
3.0.5 | 171 | 2/16/2024 |
3.0.4 | 128 | 1/25/2024 |
3.0.3 | 176 | 1/4/2024 |
3.0.2 | 214 | 11/22/2023 |
3.0.1 | 131 | 11/21/2023 |
3.0.0 | 115 | 11/20/2023 |
2.3.12 | 153 | 9/12/2023 |
2.3.11 | 163 | 9/1/2023 |
2.3.10 | 169 | 8/31/2023 |
2.3.9 | 155 | 8/31/2023 |
2.3.8 | 169 | 8/31/2023 |
2.3.7 | 175 | 8/30/2023 |
2.3.6 | 167 | 8/30/2023 |
2.3.5 | 182 | 8/30/2023 |
2.3.3 | 198 | 8/18/2023 |
2.3.2 | 209 | 8/8/2023 |
2.3.1 | 197 | 7/13/2023 |
2.3.0 | 193 | 7/11/2023 |
2.2.9 | 178 | 7/10/2023 |
2.2.8 | 223 | 6/25/2023 |
2.2.7 | 161 | 5/31/2023 |
2.2.6 | 193 | 5/17/2023 |
2.2.5 | 219 | 5/10/2023 |
2.2.4 | 244 | 4/14/2023 |
2.2.3 | 243 | 4/14/2023 |
2.2.2 | 228 | 4/14/2023 |
2.2.1 | 246 | 4/7/2023 |
2.2.0 | 275 | 3/14/2023 |
2.1.10 | 318 | 2/26/2023 |
2.1.9 | 291 | 2/26/2023 |
2.1.8 | 289 | 2/23/2023 |
2.1.7 | 286 | 2/23/2023 |
2.1.6 | 280 | 2/21/2023 |
2.1.5 | 283 | 2/21/2023 |
2.1.4 | 294 | 2/15/2023 |
2.1.3 | 307 | 2/3/2023 |
2.1.2 | 344 | 1/28/2023 |
2.1.1 | 354 | 1/22/2023 |
2.1.0 | 342 | 1/22/2023 |
2.0.8 | 357 | 1/11/2023 |
2.0.7 | 344 | 1/11/2023 |
2.0.6 | 349 | 1/9/2023 |
2.0.5 | 349 | 1/9/2023 |
2.0.4 | 422 | 11/21/2022 |
2.0.3 | 408 | 11/21/2022 |
2.0.2 | 388 | 11/19/2022 |
2.0.1 | 393 | 11/19/2022 |
2.0.0 | 374 | 11/19/2022 |
1.1.10 | 381 | 11/18/2022 |
1.1.9 | 443 | 9/27/2022 |
1.1.8 | 458 | 9/26/2022 |
1.1.7 | 488 | 9/24/2022 |
1.1.6 | 448 | 9/21/2022 |
1.1.5 | 432 | 9/19/2022 |
1.1.4 | 469 | 9/19/2022 |
1.1.3 | 447 | 9/19/2022 |
1.1.2 | 468 | 9/19/2022 |
1.1.0 | 478 | 9/17/2022 |
1.0.16 | 448 | 9/8/2022 |
1.0.15 | 471 | 8/29/2022 |
1.0.14 | 449 | 8/29/2022 |
1.0.13 | 504 | 8/29/2022 |
1.0.12 | 444 | 8/29/2022 |
1.0.11 | 449 | 8/29/2022 |
1.0.10 | 460 | 8/25/2022 |
1.0.8 | 443 | 8/25/2022 |
1.0.7 | 441 | 8/25/2022 |
1.0.6 | 444 | 8/25/2022 |
1.0.5 | 448 | 8/24/2022 |
1.0.4 | 443 | 8/23/2022 |
1.0.3 | 467 | 8/23/2022 |
1.0.2 | 455 | 8/23/2022 |
1.0.1 | 456 | 8/22/2022 |