Skip to content
This repository was archived by the owner on Apr 20, 2024. It is now read-only.

Commit c3fedd4

Browse files
author
Morten Turn Pedersen
authored
Merge pull request #3 from nodes-dotnet/feature/more-functionality
Added more functionality to the entity repository
2 parents f5a4e72 + 00164f5 commit c3fedd4

File tree

5 files changed

+234
-34
lines changed

5 files changed

+234
-34
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace Nodes.NetCore.EntityFramework.Enums
2+
{
3+
public enum GetListMode
4+
{
5+
ExcludeDeleted = 0,
6+
IncludeDeleted = 1,
7+
OnlyDeleted = 2
8+
}
9+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace Nodes.NetCore.EntityFramework.Enums
2+
{
3+
public enum OrderBy
4+
{
5+
Ascending = 0,
6+
Descending = 1
7+
}
8+
}

NetCoreEntityFramework/Models/EntityBase.cs

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -20,33 +20,5 @@ public abstract class EntityBase
2020
public DateTime? DeletedAt { get; set; }
2121

2222
public bool Deleted { get; set; }
23-
24-
public void Delete()
25-
{
26-
Deleted = true;
27-
DeletedAt = DateTime.UtcNow;
28-
}
29-
30-
/// <summary>
31-
/// Updates the database correctly
32-
/// </summary>
33-
/// <typeparam name="T">Should be same type as the model class</typeparam>
34-
/// <param name="table">The database table to delete the instance from</param>
35-
public void Delete<T>(DbSet<T> table) where T : EntityBase
36-
{
37-
if (typeof(T).FullName != GetType().FullName)
38-
{
39-
throw new ArgumentException($"Tried updating a table of type {typeof(T).FullName}. Expected type {GetType().FullName}", nameof(table));
40-
}
41-
42-
Delete();
43-
44-
table.Update(this as T);
45-
}
46-
47-
public void Restore()
48-
{
49-
Deleted = false;
50-
}
5123
}
5224
}

NetCoreEntityFramework/NetCoreEntityFramework.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<PropertyGroup>
44
<TargetFramework>netstandard2.0</TargetFramework>
55
<PackageId>Nodes.NetCore.EntityFramework.Helpers</PackageId>
6-
<Version>0.1.1</Version>
6+
<Version>0.2.0</Version>
77
<Authors>Nodes</Authors>
88
<Company>Nodes</Company>
99
<Product>.NET Core Entity Framework Helpers</Product>
Lines changed: 216 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,240 @@
11
using Microsoft.EntityFrameworkCore;
2+
using Nodes.NetCore.EntityFramework.Enums;
23
using Nodes.NetCore.EntityFramework.Models;
34
using System;
5+
using System.Collections.Generic;
6+
using System.ComponentModel.DataAnnotations;
7+
using System.Linq;
8+
using System.Linq.Expressions;
49
using System.Threading.Tasks;
510

611
namespace Nodes.NetCore.EntityFramework.Repositories
712
{
8-
public abstract class EntityRepository<T, TContext> : IDisposable where T : EntityBase where TContext : DbContext
13+
public abstract class EntityRepository<TEntity, TContext> : IDisposable where TEntity : EntityBase where TContext : DbContext
914
{
10-
protected DbSet<T> Table { get; private set; }
15+
protected DbSet<TEntity> Table { get; private set; }
1116
private TContext Context { get; set; }
1217

13-
protected EntityRepository(TContext context, DbSet<T> table)
18+
protected EntityRepository(TContext context, DbSet<TEntity> table)
1419
{
1520
Context = context;
1621
Table = table;
1722
}
1823

19-
public async Task<T> Get(Guid id)
24+
/// <summary>
25+
/// Get the entity with the given <paramref name="id"/>.
26+
/// </summary>
27+
/// <param name="id">The ID of the entity to fetch.</param>
28+
/// <param name="includeDeleted">If true, also search amongst the soft deleted entities.</param>
29+
public async Task<TEntity> Get(Guid id, bool includeDeleted = false)
2030
{
21-
return await Table.FirstOrDefaultAsync(entity => !entity.Deleted && entity.Id == id);
31+
return await Table.FirstOrDefaultAsync(entity => (includeDeleted || !entity.Deleted) && entity.Id == id);
32+
}
33+
34+
/// <summary>
35+
/// Get multiple entities paginated.
36+
/// </summary>
37+
/// <param name="page">Which page to fetch (1 and above).</param>
38+
/// <param name="pageSize">The size of each page (1 and above).</param>
39+
/// <param name="where">The filter expression.</param>
40+
/// <param name="orderByExpression">The expression to order by.</param>
41+
/// <param name="orderBy">To order by ascending or descending.</param>
42+
/// <param name="mode">Whether to include deleted or not.</param>
43+
/// <exception cref="ArgumentException"></exception>
44+
public async Task<IEnumerable<TEntity>> GetList<TKey>(
45+
[Range(1, int.MaxValue)] int page,
46+
[Range(1, int.MaxValue)] int pageSize,
47+
Expression<Func<TEntity, bool>> where = null,
48+
Expression<Func<TEntity, TKey>> orderByExpression = null,
49+
OrderBy orderBy = OrderBy.Ascending,
50+
GetListMode mode = GetListMode.ExcludeDeleted)
51+
{
52+
if (page < 1)
53+
throw new ArgumentException($"{nameof(page)} was below 1. Received: {page}", nameof(page));
54+
if(pageSize < 1)
55+
throw new ArgumentException($"{nameof(pageSize)} was below 1. Received: {pageSize}", nameof(pageSize));
56+
57+
IQueryable<TEntity> query = GetQueryable(where, orderByExpression, orderBy, mode);
58+
59+
// Pagination only skip if above page 1
60+
if (page > 1)
61+
query = query.Skip((page - 1) * pageSize);
62+
63+
query = query.Take(pageSize);
64+
65+
return await query.ToListAsync();
66+
}
67+
68+
/// <summary>
69+
/// Get multiple entities.
70+
/// </summary>
71+
/// <param name="where">The filter expression.</param>
72+
/// <param name="orderByExpression">The expression to order by.</param>
73+
/// <param name="orderBy">To order by ascending or descending.</param>
74+
/// <param name="mode">Whether to include deleted or not.</param>
75+
/// <exception cref="ArgumentException"></exception>
76+
public async Task<IEnumerable<TEntity>> GetList<TKey>(
77+
Expression<Func<TEntity, bool>> where = null,
78+
Expression<Func<TEntity, TKey>> orderByExpression = null,
79+
OrderBy orderBy = OrderBy.Ascending,
80+
GetListMode mode = GetListMode.ExcludeDeleted)
81+
{
82+
IQueryable<TEntity> query = GetQueryable(where, orderByExpression, orderBy, mode);
83+
84+
return await query.ToListAsync();
85+
}
86+
87+
/// <summary>
88+
/// Add the given <paramref name="entity"/> to the database.
89+
/// An ID will be generated if not provided.
90+
/// </summary>
91+
/// <param name="entity">The entity to add.</param>
92+
/// <exception cref="ArgumentNullException"></exception>
93+
public Task<TEntity> Add(TEntity entity)
94+
{
95+
if (entity == null)
96+
throw new ArgumentNullException(nameof(entity));
97+
98+
if (entity.Id == Guid.Empty)
99+
entity.Id = Guid.NewGuid();
100+
101+
DateTime now = DateTime.UtcNow;
102+
103+
entity.Created = now;
104+
entity.Updated = now;
105+
106+
Context.Add(entity);
107+
108+
return Task.FromResult(entity);
109+
}
110+
111+
/// <summary>
112+
/// Update the given <paramref name="entity"/> with the information set.
113+
/// </summary>
114+
/// <param name="entity">The entity to update.</param>
115+
/// <exception cref="ArgumentNullException"></exception>
116+
public Task<TEntity> Update(TEntity entity)
117+
{
118+
if (entity == null)
119+
throw new ArgumentNullException(nameof(entity));
120+
121+
entity.Updated = DateTime.UtcNow;
122+
123+
Context.Update(entity);
124+
125+
return Task.FromResult(entity);
126+
}
127+
128+
/// <summary>
129+
/// Soft delete the <paramref name="entity"/>.
130+
/// </summary>
131+
/// <param name="entity">The entity to soft delete.</param>
132+
/// <exception cref="ArgumentNullException"></exception>
133+
public Task<bool> Delete(TEntity entity)
134+
{
135+
if (entity == null)
136+
throw new ArgumentNullException(nameof(entity));
137+
138+
entity.DeletedAt = DateTime.UtcNow;
139+
entity.Deleted = true;
140+
141+
Context.Update(entity);
142+
143+
return Task.FromResult(true);
144+
}
145+
146+
/// <summary>
147+
/// Soft the delete the entity with the given <paramref name="id"/>.
148+
/// </summary>
149+
/// <param name="id">The ID of the entity to soft delete.</param>
150+
/// <exception cref="ArgumentException"></exception>
151+
public async Task<bool> Delete(Guid id)
152+
{
153+
if (id == Guid.Empty)
154+
throw new ArgumentException($"{nameof(id)} was not set", nameof(id));
155+
156+
TEntity entity = await Get(id);
157+
158+
if (entity == null)
159+
return false;
160+
161+
return await Delete(entity);
162+
}
163+
164+
/// <summary>
165+
/// Restore/undelete the entity with the given <paramref name="id"/>.
166+
/// </summary>
167+
/// <param name="id">The ID of the entity to restore.</param>
168+
/// <exception cref="ArgumentException"></exception>
169+
public async Task<bool> Restore(Guid id)
170+
{
171+
if (id == Guid.Empty)
172+
throw new ArgumentException($"{nameof(id)} was not set", nameof(id));
173+
174+
TEntity entity = await Get(id, true);
175+
176+
if (entity == null)
177+
return false;
178+
179+
return await Restore(entity);
180+
}
181+
182+
/// <summary>
183+
/// Restore/undelete the given <paramref name="entity"/>.
184+
/// </summary>
185+
/// <param name="entity">The entity to restore.</param>
186+
/// <exception cref="ArgumentNullException"></exception>
187+
public Task<bool> Restore(TEntity entity)
188+
{
189+
if (entity == null)
190+
throw new ArgumentNullException(nameof(entity));
191+
192+
entity.Deleted = false;
193+
194+
Context.Update(entity);
195+
196+
return Task.FromResult(true);
22197
}
23198

24199
public void Dispose()
25200
{
26201
Context.SaveChanges();
27202
}
203+
204+
private IQueryable<TEntity> GetQueryable<TKey>(
205+
Expression<Func<TEntity, bool>> where = null,
206+
Expression<Func<TEntity, TKey>> orderByExpression = null,
207+
OrderBy orderBy = OrderBy.Ascending,
208+
GetListMode mode = GetListMode.ExcludeDeleted)
209+
{
210+
IQueryable<TEntity> query;
211+
212+
switch (mode)
213+
{
214+
case GetListMode.ExcludeDeleted:
215+
query = Table.Where(e => !e.Deleted);
216+
break;
217+
case GetListMode.IncludeDeleted:
218+
query = Table;
219+
break;
220+
case GetListMode.OnlyDeleted:
221+
query = Table.Where(e => e.Deleted);
222+
break;
223+
default:
224+
throw new ArgumentException("Unknown setting", nameof(mode));
225+
}
226+
227+
if (where != null)
228+
query = query.Where(where);
229+
230+
if (orderByExpression != null)
231+
{
232+
query = orderBy == OrderBy.Ascending
233+
? query.OrderBy(orderByExpression)
234+
: query.OrderByDescending(orderByExpression);
235+
}
236+
237+
return query;
238+
}
28239
}
29240
}

0 commit comments

Comments
 (0)