Skip to content

Commit 61cd442

Browse files
authored
Merge pull request #2 from BlaiseD/master
Added more details to ReadMe.md
2 parents 35218e9 + da794ab commit 61cd442

File tree

1 file changed

+76
-1
lines changed

1 file changed

+76
-1
lines changed

README.md

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
## OData
12
AutoMapper extentions for mapping expressions (OData)
23

34
To use, configure using the configuration helper method:
@@ -7,4 +8,78 @@ Mapper.Initialize(cfg => {
78
cfg.AddExpressionMapping();
89
// Rest of your configuration
910
});
10-
```
11+
```
12+
13+
## DTO Queries
14+
Expression Mapping also supports writing queries against the mapped objects. Take the following source and destination types:
15+
```csharp
16+
public class User
17+
{
18+
public int Id { get; set; }
19+
public string Name { get; set; }
20+
}
21+
22+
public class Request
23+
{
24+
public int Id { get; set; }
25+
public int AssigneeId { get; set; }
26+
public User Assignee { get; set; }
27+
}
28+
29+
public class UserDTO
30+
{
31+
public int Id { get; set; }
32+
public string Name { get; set; }
33+
}
34+
35+
public class RequestDTO
36+
{
37+
public int Id { get; set; }
38+
public UserDTO Assignee { get; set; }
39+
}
40+
```
41+
42+
We can write LINQ expressions against the DTO collections.
43+
```csharp
44+
ICollection<RequestDTO> requests = await context.Request.GetItemsAsync(mapper, r => r.Id > 0 && r.Id < 3, null, new List<Expression<Func<IQueryable<RequestDTO>, IIncludableQueryable<RequestDTO, object>>>>() { item => item.Include(s => s.Assignee) });
45+
ICollection<UserDTO> users = await context.User.GetItemsAsync<UserDTO, User>(mapper, u => u.Id > 0 && u.Id < 4, q => q.OrderBy(u => u.Name));
46+
int count = await context.Request.Query<RequestDTO, Request, int, int>(mapper, q => q.Count(r => r.Id > 1));
47+
```
48+
The methods below map the DTO query expresions to the equivalent data query expressions. The call to IMapper.Map converts the data query results back to the DTO (or model) object types.
49+
```csharp
50+
static class Extensions
51+
{
52+
internal static async Task<TModelResult> Query<TModel, TData, TModelResult, TDataResult>(this IQueryable<TData> query, IMapper mapper,
53+
Expression<Func<IQueryable<TModel>, TModelResult>> queryFunc) where TData : class
54+
{
55+
//Map the expressions
56+
Func<IQueryable<TData>, TDataResult> mappedQueryFunc = mapper.MapExpression<Expression<Func<IQueryable<TData>, TDataResult>>>(queryFunc).Compile();
57+
58+
//execute the query
59+
return mapper.Map<TDataResult, TModelResult>(mappedQueryFunc(query));
60+
}
61+
62+
internal static async Task<ICollection<TModel>> GetItemsAsync<TModel, TData>(this IQueryable<TData> query, IMapper mapper,
63+
Expression<Func<TModel, bool>> filter = null,
64+
Expression<Func<IQueryable<TModel>, IQueryable<TModel>>> queryFunc = null,
65+
ICollection<Expression<Func<IQueryable<TModel>, IIncludableQueryable<TModel, object>>>> includeProperties = null)
66+
{
67+
//Map the expressions
68+
Expression<Func<TData, bool>> f = mapper.MapExpression<Expression<Func<TData, bool>>>(filter);
69+
Func<IQueryable<TData>, IQueryable<TData>> mappedQueryFunc = mapper.MapExpression<Expression<Func<IQueryable<TData>, IQueryable<TData>>>>(queryFunc)?.Compile();
70+
ICollection<Expression<Func<IQueryable<TData>, IIncludableQueryable<TData, object>>>> includes = mapper.MapIncludesList<Expression<Func<IQueryable<TData>, IIncludableQueryable<TData, object>>>>(includeProperties);
71+
72+
if (f != null)
73+
query = query.Where(f);
74+
75+
if (includes != null)
76+
query = includes.Select(i => i.Compile()).Aggregate(query, (list, next) => query = next(query));
77+
78+
//Call the store
79+
ICollection<TData> result = mappedQueryFunc != null ? await mappedQueryFunc(query).ToListAsync() : await query.ToListAsync();
80+
81+
//Map and return the data
82+
return mapper.Map<IEnumerable<TData>, IEnumerable<TModel>>(result).ToList();
83+
}
84+
}
85+
```

0 commit comments

Comments
 (0)