Skip to content

Commit b616f64

Browse files
committed
Merge branch 'master' into feat/#494
2 parents 4abcb3c + 2cc9c14 commit b616f64

File tree

6 files changed

+69
-9
lines changed

6 files changed

+69
-9
lines changed

src/JsonApiDotNetCore/Data/DefaultEntityRepository.cs

+16-3
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ public DefaultEntityRepository(
7878
_resourceDefinition = resourceDefinition;
7979
}
8080

81-
/// <inheritdoc />
81+
82+
8283
public virtual IQueryable<TEntity> Get()
8384
{
8485
if (_jsonApiContext.QuerySet?.Fields != null && _jsonApiContext.QuerySet.Fields.Count > 0)
@@ -87,6 +88,18 @@ public virtual IQueryable<TEntity> Get()
8788
return _dbSet;
8889
}
8990

91+
/// <inheritdoc />
92+
public virtual IQueryable<TEntity> GetQueryable()
93+
=> _dbSet;
94+
95+
public virtual IQueryable<TEntity> Select(IQueryable<TEntity> entities, List<string> fields)
96+
{
97+
if (fields?.Count > 0)
98+
return entities.Select(fields);
99+
100+
return entities;
101+
}
102+
90103
/// <inheritdoc />
91104
public virtual IQueryable<TEntity> Filter(IQueryable<TEntity> entities, FilterQuery filterQuery)
92105
{
@@ -127,15 +140,15 @@ public virtual IQueryable<TEntity> Sort(IQueryable<TEntity> entities, List<SortQ
127140
/// <inheritdoc />
128141
public virtual async Task<TEntity> GetAsync(TId id)
129142
{
130-
return await Get().SingleOrDefaultAsync(e => e.Id.Equals(id));
143+
return await GetQueryable().SingleOrDefaultAsync(e => e.Id.Equals(id));
131144
}
132145

133146
/// <inheritdoc />
134147
public virtual async Task<TEntity> GetAndIncludeAsync(TId id, string relationshipName)
135148
{
136149
_logger?.LogDebug($"[JADN] GetAndIncludeAsync({id}, {relationshipName})");
137150

138-
var includedSet = Include(Get(), relationshipName);
151+
var includedSet = Include(GetQueryable(), relationshipName);
139152
var result = await includedSet.SingleOrDefaultAsync(e => e.Id.Equals(id));
140153

141154
return result;

src/JsonApiDotNetCore/Data/IEntityReadRepository.cs

+9
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System;
12
using System.Collections.Generic;
23
using System.Linq;
34
using System.Threading.Tasks;
@@ -18,8 +19,16 @@ public interface IEntityReadRepository<TEntity, in TId>
1819
/// The base GET query. This is a good place to apply rules that should affect all reads,
1920
/// such as authorization of resources.
2021
/// </summary>
22+
IQueryable<TEntity> GetQueryable();
23+
24+
[Obsolete("This method has been deprecated, use GetQueryable() instead")]
2125
IQueryable<TEntity> Get();
2226

27+
/// <summary>
28+
/// Apply fields to the provided queryable
29+
/// </summary>
30+
IQueryable<TEntity> Select(IQueryable<TEntity> entities,List<string> fields);
31+
2332
/// <summary>
2433
/// Include a relationship in the query
2534
/// </summary>

src/JsonApiDotNetCore/Services/EntityResourceService.cs

+5-2
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ public virtual async Task<bool> DeleteAsync(TId id)
9898

9999
public virtual async Task<IEnumerable<TResource>> GetAsync()
100100
{
101-
var entities = _entities.Get();
101+
var entities = _entities.GetQueryable();
102102

103103
entities = ApplySortAndFilterQuery(entities);
104104

@@ -108,6 +108,9 @@ public virtual async Task<IEnumerable<TResource>> GetAsync()
108108
if (_jsonApiContext.Options.IncludeTotalRecordCount)
109109
_jsonApiContext.PageManager.TotalRecords = await _entities.CountAsync(entities);
110110

111+
if (_jsonApiContext.QuerySet?.Fields?.Count > 0)
112+
entities = _entities.Select(entities, _jsonApiContext.QuerySet.Fields);
113+
111114
// pagination should be done last since it will execute the query
112115
var pagedEntities = await ApplyPageQueryAsync(entities);
113116
return pagedEntities;
@@ -240,7 +243,7 @@ protected virtual IQueryable<TEntity> IncludeRelationships(IQueryable<TEntity> e
240243

241244
private async Task<TResource> GetWithRelationshipsAsync(TId id)
242245
{
243-
var query = _entities.Get().Where(e => e.Id.Equals(id));
246+
var query = _entities.GetQueryable().Where(e => e.Id.Equals(id));
244247

245248
_jsonApiContext.QuerySet.IncludedRelationships.ForEach(r =>
246249
{

test/DiscoveryTests/ServiceDiscoveryFacadeTests.cs

-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System;
21
using GettingStarted.Models;
32
using GettingStarted.ResourceDefinitionExample;
43
using JsonApiDotNetCore.Builders;
@@ -7,7 +6,6 @@
76
using JsonApiDotNetCore.Models;
87
using JsonApiDotNetCore.Services;
98
using Microsoft.Extensions.DependencyInjection;
10-
using Microsoft.Extensions.Logging;
119
using Moq;
1210
using Xunit;
1311

test/JsonApiDotNetCoreExampleTests/Acceptance/Extensibility/RepositoryOverrideTests.cs

+37
Original file line numberDiff line numberDiff line change
@@ -61,5 +61,42 @@ public async Task Total_Record_Count_Included()
6161
foreach(var item in deserializedBody)
6262
Assert.Equal(person.Id, item.OwnerId);
6363
}
64+
65+
[Fact]
66+
public async Task Sparse_Fields_Works_With_Get_Override()
67+
{
68+
// arrange
69+
var builder = new WebHostBuilder()
70+
.UseStartup<AuthorizedStartup>();
71+
var server = new TestServer(builder);
72+
var client = server.CreateClient();
73+
var context = (AppDbContext)server.Host.Services.GetService(typeof(AppDbContext));
74+
var jsonApiContext = (IJsonApiContext)server.Host.Services.GetService(typeof(IJsonApiContext));
75+
76+
var person = new Person();
77+
context.People.Add(person);
78+
var todoItem = new TodoItem();
79+
todoItem.Owner = person;
80+
context.TodoItems.Add(todoItem);
81+
context.SaveChanges();
82+
83+
var authService = (IAuthorizationService)server.Host.Services.GetService(typeof(IAuthorizationService));
84+
authService.CurrentUserId = person.Id;
85+
86+
var httpMethod = new HttpMethod("GET");
87+
var route = $"/api/v1/todo-items/{todoItem.Id}?fields[todo-items]=description";
88+
89+
var request = new HttpRequestMessage(httpMethod, route);
90+
91+
// act
92+
var response = await client.SendAsync(request);
93+
var responseBody = await response.Content.ReadAsStringAsync();
94+
var deserializedBody = _fixture.GetService<IJsonApiDeSerializer>().Deserialize<TodoItem>(responseBody);
95+
96+
// assert
97+
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
98+
Assert.Equal(todoItem.Description, deserializedBody.Description);
99+
100+
}
64101
}
65102
}

test/JsonApiDotNetCoreExampleTests/Helpers/Repositories/AuthorizedTodoItemsRepository.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ public AuthorizedTodoItemsRepository(
2323
_authService = authService;
2424
}
2525

26-
public override IQueryable<TodoItem> Get()
26+
public override IQueryable<TodoItem> GetQueryable()
2727
{
28-
return base.Get().Where(todoItem => todoItem.OwnerId == _authService.CurrentUserId);
28+
return base.GetQueryable().Where(todoItem => todoItem.OwnerId == _authService.CurrentUserId);
2929
}
3030
}
3131
}

0 commit comments

Comments
 (0)