From b63d205057af361b6bb0e5bacc031a735b273e8c Mon Sep 17 00:00:00 2001 From: Edgar Mesquita Date: Mon, 4 Sep 2023 22:17:50 +0100 Subject: [PATCH] feat: Implementing generic Get Entity By Id Specification --- .../Extensions/DbContextExtensions.cs | 42 +++++++++++++++++++ src/Repository/Set.cs | 30 +------------ src/Repository/UnitOfWork.cs | 2 + .../GetEntityByIdSpecification.cs | 25 +++++++++++ src/eQuantic.Core.Data.EntityFramework.csproj | 6 +-- 5 files changed, 73 insertions(+), 32 deletions(-) create mode 100644 src/Repository/Extensions/DbContextExtensions.cs create mode 100644 src/Specifications/GetEntityByIdSpecification.cs diff --git a/src/Repository/Extensions/DbContextExtensions.cs b/src/Repository/Extensions/DbContextExtensions.cs new file mode 100644 index 0000000..95d95f8 --- /dev/null +++ b/src/Repository/Extensions/DbContextExtensions.cs @@ -0,0 +1,42 @@ +using System; +using System.Linq; +using System.Linq.Expressions; +using Microsoft.EntityFrameworkCore; + +namespace eQuantic.Core.Data.EntityFramework.Repository.Extensions; + +public static class DbContextExtensions +{ + public static Expression> GetFindByKeyExpression(this DbContext dbContext, TKey id) + { + var primaryKey = dbContext.Model.FindEntityType(typeof(TEntity))!.FindPrimaryKey()!.Properties + .FirstOrDefault(); + if (primaryKey == null) + { + return null; + } + + var keyProperty = typeof(TEntity).GetProperty(primaryKey.Name); + + if (keyProperty == null) + { + return null; + } + + // Create entity => portion of lambda expression + var parameter = Expression.Parameter(typeof(TEntity), "entity"); + + // create entity.Id portion of lambda expression + var property = Expression.Property(parameter, keyProperty.Name); + + // create 'id' portion of lambda expression + var equalsTo = Expression.Constant(id); + + // create entity.Id == 'id' portion of lambda expression + var equality = Expression.Equal(property, equalsTo); + + // finally create entire expression - entity => entity.Id == 'id' + var retVal = Expression.Lambda>(equality, new[] { parameter }); + return retVal; + } +} \ No newline at end of file diff --git a/src/Repository/Set.cs b/src/Repository/Set.cs index a399640..18a744a 100644 --- a/src/Repository/Set.cs +++ b/src/Repository/Set.cs @@ -373,35 +373,7 @@ private async Task LoadCascadeAsync(string[] props, object obj, int index = 0) internal Expression> GetExpression(TKey id) { - var primaryKey = _dbContext.Model.FindEntityType(typeof(TEntity))!.FindPrimaryKey()!.Properties - .FirstOrDefault(); - if (primaryKey == null) - { - return null; - } - - var keyProperty = typeof(TEntity).GetProperty(primaryKey.Name); - - if (keyProperty == null) - { - return null; - } - - // Create entity => portion of lambda expression - var parameter = Expression.Parameter(typeof(TEntity), "entity"); - - // create entity.Id portion of lambda expression - var property = Expression.Property(parameter, keyProperty.Name); - - // create 'id' portion of lambda expression - var equalsTo = Expression.Constant(id); - - // create entity.Id == 'id' portion of lambda expression - var equality = Expression.Equal(property, equalsTo); - - // finally create entire expression - entity => entity.Id == 'id' - var retVal = Expression.Lambda>(equality, new[] { parameter }); - return retVal; + return _dbContext.GetFindByKeyExpression(id); } private static TConfig GetConfig(Action configuration) diff --git a/src/Repository/UnitOfWork.cs b/src/Repository/UnitOfWork.cs index 242336e..25a0e5f 100644 --- a/src/Repository/UnitOfWork.cs +++ b/src/Repository/UnitOfWork.cs @@ -20,6 +20,8 @@ public abstract class UnitOfWork : SqlExecutor protected UnitOfWork(DbContext context) : base(context) { } + + internal DbContext GetDbContext() => Context; } public abstract class UnitOfWork : UnitOfWork, ISqlUnitOfWork diff --git a/src/Specifications/GetEntityByIdSpecification.cs b/src/Specifications/GetEntityByIdSpecification.cs new file mode 100644 index 0000000..cf5cd53 --- /dev/null +++ b/src/Specifications/GetEntityByIdSpecification.cs @@ -0,0 +1,25 @@ +using System; +using System.Linq.Expressions; +using eQuantic.Core.Data.EntityFramework.Repository; +using eQuantic.Core.Data.EntityFramework.Repository.Extensions; +using eQuantic.Core.Data.Repository; +using eQuantic.Linq.Specification; + +namespace eQuantic.Core.Data.EntityFramework.Specifications; + +public class GetEntityByIdSpecification : Specification + where TEntity : class, IEntity, new() +{ + private readonly TKey _id; + private readonly UnitOfWork _unitOfWork; + + public GetEntityByIdSpecification(TKey id, UnitOfWork unitOfWork) + { + _id = id; + _unitOfWork = unitOfWork; + } + public override Expression> SatisfiedBy() + { + return _unitOfWork.GetDbContext().GetFindByKeyExpression(_id); + } +} \ No newline at end of file diff --git a/src/eQuantic.Core.Data.EntityFramework.csproj b/src/eQuantic.Core.Data.EntityFramework.csproj index c1a4b5f..93fc1aa 100644 --- a/src/eQuantic.Core.Data.EntityFramework.csproj +++ b/src/eQuantic.Core.Data.EntityFramework.csproj @@ -4,7 +4,7 @@ Core Data library for Entity Framework eQuantic.Core.Data.EntityFramework - 4.0.3.0 + 4.0.4.0 eQuantic Systems netstandard2.1;net6.0;net7.0 eQuantic.Core.Data.EntityFramework @@ -23,8 +23,8 @@ LICENSE README.md Copyright © 2016 - 4.0.3.0 - 4.0.3.0 + 4.0.4.0 + 4.0.4.0 Icon.png latest