Created
January 4, 2018 17:46
-
-
Save cristipufu/bef7af3658da3a3e65e963e54522ff08 to your computer and use it in GitHub Desktop.
OData AutoMapper translate DTO queries to POCO queries
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[HttpGet] | |
public async Task<IEnumerable<AddressModel>> GetAddresses(ODataQueryOptions<AddressModel> queryOptions, CancellationToken cancellationToken) | |
{ | |
var repository = new AddressRepository(_context); | |
var service = new AddressService(repository); | |
var filter = queryOptions.ToModelQueryFilter<AddressModel>(); | |
return await service.QueryByStreetAsync("StreetName", filter, cancellationToken); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public Task<List<Address>> QueryByStreetAsync(string street, IQueryFilter<Address> filter, CancellationToken cancellationToken) | |
{ | |
var query = AsQueryable() | |
.Apply(filter); | |
return QueryAsync(query, cancellationToken); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public async Task<IEnumerable<AddressModel>> QueryByStreetAsync( | |
string streetName, | |
ModelQueryFilter<AddressModel> modelFilter, | |
CancellationToken cancellationToken) | |
{ | |
var queryFilter = modelFilter.Map<Address>(); | |
var addresses = await _addressManager.QueryByStreetAsync(streetName, queryFilter, CancellationToken.None); | |
return addresses.Select(Mapper.Map<AddressModel>); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static class IQueryableExtensions | |
{ | |
public static IQueryable<T> Apply<T>(this IQueryable<T> query, IQueryFilter<T> filter) | |
{ | |
if (filter == null) return query; | |
var action = filter.FilterExpression.Compile(); | |
return action(query); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ModelQueryFilter<TDto> | |
{ | |
public Expression<Func<IQueryable<TDto>, IQueryable<TDto>>> FilterExpression { get; set; } | |
public IQueryFilter<TPoco> Map<TPoco>() | |
{ | |
var expression = Mapper.Instance.Map<Expression<Func<IQueryable<TPoco>, IQueryable<TPoco>>>>(FilterExpression); | |
return new QueryFilter<TPoco> | |
{ | |
FilterExpression = expression, | |
}; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static class ODataQueryOptionsExtensions | |
{ | |
public static ModelQueryFilter<TDto> ToModelQueryFilter<TDto>(this ODataQueryOptions options) | |
{ | |
Expression<Func<IQueryable<TDto>, IQueryable<TDto>>> expression; | |
var query = (IQueryable<TDto>)options.ApplyTo(Enumerable.Empty<TDto>().AsQueryable()); | |
var param = Expression.Parameter(typeof(IQueryable<TDto>), "x"); | |
if (query.Expression is MethodCallExpression methodCall) | |
{ | |
var xArg = methodCall.Arguments[1]; | |
var m = methodCall.Update(methodCall.Object, new List<Expression> {param, xArg}); | |
expression = Expression.Lambda<Func<IQueryable<TDto>, IQueryable<TDto>>>(m, param); | |
} | |
else | |
{ | |
expression = x => x; | |
} | |
var result = new ModelQueryFilter<TDto> | |
{ | |
FilterExpression = expression | |
}; | |
return result; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment