Skip to content

Commit 7418787

Browse files
committed
add GenericDataAccessAbstraction
Closes #9
1 parent 7c0f6a8 commit 7418787

File tree

3 files changed

+63
-24
lines changed

3 files changed

+63
-24
lines changed

JsonApiDotNetCore/Data/GenericDataAccess.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public IQueryable<T> IncludeEntity<T>(IQueryable<T> queryable, string includedEn
1919
return queryable.Include(includedEntityName);
2020
}
2121

22-
public T SingleOrDefault<T>(object query, string param, string value)
22+
public T SingleOrDefault<T>(object query, string param, object value)
2323
{
2424
var queryable = (IQueryable<T>) query;
2525
var currentType = queryable.ElementType;
@@ -30,9 +30,16 @@ public T SingleOrDefault<T>(object query, string param, string value)
3030
throw new ArgumentException($"'{param}' is not a valid property of '{currentType}'");
3131
}
3232

33-
var prm = Expression.Parameter(currentType, property.Name);
34-
var left = Expression.Convert(Expression.PropertyOrField(prm, property.Name), typeof(string));
35-
var right = Expression.Constant(1, property.PropertyType);
33+
// convert the incoming value to the target value type
34+
// "1" -> 1
35+
var convertedValue = Convert.ChangeType(value, property.PropertyType);
36+
// {model}
37+
var prm = Expression.Parameter(currentType, "model");
38+
// {model.Id}
39+
var left = Expression.PropertyOrField(prm, property.Name);
40+
// {1}
41+
var right = Expression.Constant(convertedValue, property.PropertyType);
42+
// {model.Id == 1}
3643
var body = Expression.Equal(left, right);
3744
var where = Expression.Lambda<Func<T, bool>>(body, prm);
3845

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using System;
2+
using System.Reflection;
3+
using System.Linq;
4+
using System.Linq.Expressions;
5+
using JsonApiDotNetCore.Extensions;
6+
using Microsoft.EntityFrameworkCore;
7+
8+
namespace JsonApiDotNetCore.Data
9+
{
10+
public class GenericDataAccessAbstraction
11+
{
12+
private GenericDataAccess _dataAccessorInstance;
13+
private DbContext _dbContext;
14+
private Type _modelType;
15+
private string _includedRelationship;
16+
public GenericDataAccessAbstraction(object dbContext, Type modelType, string includedRelationship)
17+
{
18+
_dataAccessorInstance = (GenericDataAccess)Activator.CreateInstance(typeof(GenericDataAccess));
19+
_dbContext = (DbContext) dbContext;
20+
_modelType = modelType;
21+
_includedRelationship = includedRelationship?.ToProperCase();
22+
}
23+
24+
public object SingleOrDefault(string id)
25+
{
26+
var dbSet = GetDbSet();
27+
if (!string.IsNullOrEmpty(_includedRelationship))
28+
{
29+
dbSet = IncludeRelationshipInContext(dbSet);
30+
}
31+
var dataAccessorSingleOrDefaultMethod = _dataAccessorInstance.GetType().GetMethod("SingleOrDefault");
32+
var genericSingleOrDefaultMethod = dataAccessorSingleOrDefaultMethod.MakeGenericMethod(_modelType);
33+
return genericSingleOrDefaultMethod.Invoke(_dataAccessorInstance, new[] { dbSet, "Id", id });
34+
}
35+
36+
private object GetDbSet()
37+
{
38+
var dataAccessorGetDbSetMethod = _dataAccessorInstance.GetType().GetMethod("GetDbSet");
39+
var genericGetDbSetMethod = dataAccessorGetDbSetMethod.MakeGenericMethod(_modelType);
40+
return genericGetDbSetMethod.Invoke(_dataAccessorInstance, new [] { _dbContext });
41+
}
42+
43+
private object IncludeRelationshipInContext(object dbSet)
44+
{
45+
var includeMethod = _dataAccessorInstance.GetType().GetMethod("IncludeEntity");
46+
var genericIncludeMethod = includeMethod.MakeGenericMethod(_modelType);
47+
return genericIncludeMethod.Invoke(_dataAccessorInstance, new []{ dbSet, _includedRelationship });
48+
}
49+
50+
}
51+
}

JsonApiDotNetCore/Data/ResourceRepository.cs

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -43,26 +43,7 @@ private IQueryable GetDbSetFromContext(string propName)
4343

4444
private object GetEntityById(Type modelType, string id, string includedRelationship)
4545
{
46-
// get generic dbSet
47-
var dataAccessorInstance = Activator.CreateInstance(typeof(GenericDataAccess));
48-
var dataAccessorGetDbSetMethod = dataAccessorInstance.GetType().GetMethod("GetDbSet");
49-
var genericGetDbSetMethod = dataAccessorGetDbSetMethod.MakeGenericMethod(modelType);
50-
var dbSet = genericGetDbSetMethod.Invoke(dataAccessorInstance, new [] {((DbContext) _context.DbContext) });
51-
52-
// include relationships if requested
53-
if (!string.IsNullOrEmpty(includedRelationship))
54-
{
55-
var includeMethod = dataAccessorInstance.GetType().GetMethod("IncludeEntity");
56-
var genericIncludeMethod = includeMethod.MakeGenericMethod(modelType);
57-
dbSet = genericIncludeMethod.Invoke(dataAccessorInstance, new []{ dbSet, includedRelationship.ToProperCase() });
58-
}
59-
60-
// get the SingleOrDefault value by Id
61-
var dataAccessorSingleOrDefaultMethod = dataAccessorInstance.GetType().GetMethod("SingleOrDefault");
62-
var genericSingleOrDefaultMethod = dataAccessorSingleOrDefaultMethod.MakeGenericMethod(modelType);
63-
var entity = genericSingleOrDefaultMethod.Invoke(dataAccessorInstance, new[] { dbSet, "Id", id });
64-
65-
return entity;
46+
return new GenericDataAccessAbstraction(_context.DbContext, modelType, includedRelationship).SingleOrDefault(id);;
6647
}
6748

6849
public void Add(object entity)

0 commit comments

Comments
 (0)