Skip to content

Commit

Permalink
feat: Implementing generic Get Entity By Id Specification
Browse files Browse the repository at this point in the history
  • Loading branch information
Edgar Mesquita authored and Edgar Mesquita committed Sep 4, 2023
1 parent 885e0d4 commit b63d205
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 32 deletions.
42 changes: 42 additions & 0 deletions src/Repository/Extensions/DbContextExtensions.cs
Original file line number Diff line number Diff line change
@@ -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<Func<TEntity, bool>> GetFindByKeyExpression<TEntity, TKey>(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<Func<TEntity, bool>>(equality, new[] { parameter });
return retVal;
}
}
30 changes: 1 addition & 29 deletions src/Repository/Set.cs
Original file line number Diff line number Diff line change
Expand Up @@ -373,35 +373,7 @@ private async Task LoadCascadeAsync(string[] props, object obj, int index = 0)

internal Expression<Func<TEntity, bool>> GetExpression<TKey>(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<Func<TEntity, bool>>(equality, new[] { parameter });
return retVal;
return _dbContext.GetFindByKeyExpression<TEntity, TKey>(id);
}

private static TConfig GetConfig<TConfig>(Action<TConfig> configuration)
Expand Down
2 changes: 2 additions & 0 deletions src/Repository/UnitOfWork.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ public abstract class UnitOfWork : SqlExecutor
protected UnitOfWork(DbContext context) : base(context)
{
}

internal DbContext GetDbContext() => Context;
}

public abstract class UnitOfWork<TUnitOfWork, TDbContext> : UnitOfWork<TDbContext>, ISqlUnitOfWork<TUnitOfWork>
Expand Down
25 changes: 25 additions & 0 deletions src/Specifications/GetEntityByIdSpecification.cs
Original file line number Diff line number Diff line change
@@ -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<TEntity, TKey> : Specification<TEntity>
where TEntity : class, IEntity<TKey>, new()
{
private readonly TKey _id;
private readonly UnitOfWork _unitOfWork;

public GetEntityByIdSpecification(TKey id, UnitOfWork unitOfWork)
{
_id = id;
_unitOfWork = unitOfWork;
}
public override Expression<Func<TEntity, bool>> SatisfiedBy()
{
return _unitOfWork.GetDbContext().GetFindByKeyExpression<TEntity, TKey>(_id);
}
}
6 changes: 3 additions & 3 deletions src/eQuantic.Core.Data.EntityFramework.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<PropertyGroup>
<Description>Core Data library for Entity Framework</Description>
<AssemblyTitle>eQuantic.Core.Data.EntityFramework</AssemblyTitle>
<Version>4.0.3.0</Version>
<Version>4.0.4.0</Version>
<Authors>eQuantic Systems</Authors>
<TargetFrameworks>netstandard2.1;net6.0;net7.0</TargetFrameworks>
<AssemblyName>eQuantic.Core.Data.EntityFramework</AssemblyName>
Expand All @@ -23,8 +23,8 @@
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<PackageReadmeFile>README.md</PackageReadmeFile>
<Copyright>Copyright © 2016</Copyright>
<AssemblyVersion>4.0.3.0</AssemblyVersion>
<FileVersion>4.0.3.0</FileVersion>
<AssemblyVersion>4.0.4.0</AssemblyVersion>
<FileVersion>4.0.4.0</FileVersion>
<PackageIcon>Icon.png</PackageIcon>
<LangVersion>latest</LangVersion>
</PropertyGroup>
Expand Down

0 comments on commit b63d205

Please sign in to comment.