-
-
Notifications
You must be signed in to change notification settings - Fork 158
/
Copy pathDefaultEntityRepository.cs
159 lines (130 loc) · 5.44 KB
/
DefaultEntityRepository.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using JsonApiDotNetCore.Extensions;
using JsonApiDotNetCore.Internal;
using JsonApiDotNetCore.Internal.Query;
using JsonApiDotNetCore.Models;
using JsonApiDotNetCore.Services;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
namespace JsonApiDotNetCore.Data
{
public class DefaultEntityRepository<TEntity>
: DefaultEntityRepository<TEntity, int>,
IEntityRepository<TEntity>
where TEntity : class, IIdentifiable<int>
{
public DefaultEntityRepository(
DbContext context,
ILoggerFactory loggerFactory,
IJsonApiContext jsonApiContext)
: base(context, loggerFactory, jsonApiContext)
{ }
}
public class DefaultEntityRepository<TEntity, TId>
: IEntityRepository<TEntity, TId>
where TEntity : class, IIdentifiable<TId>
{
private readonly DbContext _context;
private readonly DbSet<TEntity> _dbSet;
private readonly ILogger _logger;
private readonly IJsonApiContext _jsonApiContext;
private readonly IGenericProcessorFactory _genericProcessorFactory;
public DefaultEntityRepository(
DbContext context,
ILoggerFactory loggerFactory,
IJsonApiContext jsonApiContext)
{
_context = context;
_dbSet = context.GetDbSet<TEntity>();
_jsonApiContext = jsonApiContext;
_logger = loggerFactory.CreateLogger<DefaultEntityRepository<TEntity, TId>>();
_genericProcessorFactory = _jsonApiContext.GenericProcessorFactory;
}
public virtual IQueryable<TEntity> Get()
{
return _dbSet.Select(_jsonApiContext.QuerySet?.Fields);
}
public virtual IQueryable<TEntity> Filter(IQueryable<TEntity> entities, FilterQuery filterQuery)
{
if(filterQuery == null)
return entities;
if(filterQuery.IsAttributeOfRelationship)
return entities.Filter(new RelatedAttrFilterQuery(_jsonApiContext, filterQuery));
else
return entities.Filter(new AttrFilterQuery(_jsonApiContext, filterQuery));
}
public virtual IQueryable<TEntity> Sort(IQueryable<TEntity> entities, List<SortQuery> sortQueries)
{
if(sortQueries == null || sortQueries.Count == 0)
return entities;
var orderedEntities = entities.Sort(sortQueries[0]);
if(sortQueries.Count() > 1)
for(var i=1; i < sortQueries.Count(); i++)
orderedEntities = orderedEntities.Sort(sortQueries[i]);
return orderedEntities;
}
public virtual async Task<TEntity> GetAsync(TId id)
{
return await Get().SingleOrDefaultAsync(e => e.Id.Equals(id));
}
public virtual async Task<TEntity> GetAndIncludeAsync(TId id, string relationshipName)
{
return await Get()
.Include(relationshipName)
.SingleOrDefaultAsync(e => e.Id.Equals(id));
}
public virtual async Task<TEntity> CreateAsync(TEntity entity)
{
_dbSet.Add(entity);
await _context.SaveChangesAsync();
return entity;
}
public virtual async Task<TEntity> UpdateAsync(TId id, TEntity entity)
{
var oldEntity = await GetAsync(id);
if (oldEntity == null)
return null;
_jsonApiContext.RequestEntity.Attributes.ForEach(attr =>
{
attr.SetValue(oldEntity, attr.GetValue(entity));
});
foreach(var relationship in _jsonApiContext.RelationshipsToUpdate)
relationship.Key.SetValue(oldEntity, relationship.Value);
await _context.SaveChangesAsync();
return oldEntity;
}
public async Task UpdateRelationshipsAsync(object parent, RelationshipAttribute relationship, IEnumerable<string> relationshipIds)
{
var genericProcessor = _genericProcessorFactory.GetProcessor(relationship.Type);
await genericProcessor.UpdateRelationshipsAsync(parent, relationship, relationshipIds);
}
public virtual async Task<bool> DeleteAsync(TId id)
{
var entity = await GetAsync(id);
if (entity == null)
return false;
_dbSet.Remove(entity);
await _context.SaveChangesAsync();
return true;
}
public virtual IQueryable<TEntity> Include(IQueryable<TEntity> entities, string relationshipName)
{
var entity = _jsonApiContext.RequestEntity;
if(entity.Relationships.Any(r => r.InternalRelationshipName == relationshipName))
return entities.Include(relationshipName);
throw new JsonApiException("400", "Invalid relationship",
$"{entity.EntityName} does not have a relationship named {relationshipName}");
}
public virtual async Task<IEnumerable<TEntity>> PageAsync(IQueryable<TEntity> entities, int pageSize, int pageNumber)
{
if(pageSize > 0)
return await entities
.Skip((pageNumber - 1) * pageSize)
.Take(pageSize)
.ToListAsync();
return await entities.ToListAsync();
}
}
}