I know the title is not good.
I have a service that contain all of my entity functions.
In my service there is a function with this structure
IList<T> GetAllPaged<TKey>(
List<Expression<Func<T, bool>>> predicate,
Expression<Func<T, TKey>> orderKeySelector
);
This function gets data from one entity and orders it.
Now I want to do more.
First to select from one entity then group it in order it and at the end select new items from grouped items.
Something like this:
IList<TReturn> GetAllPaged<TResult, TKey, TGroup, TReturn>(
List<Expression<Func<T, bool>>> predicate,
Expression<Func<T, TResult>> firstSelector,
Expression<Func<TResult, TKey>> orderSelector,
Func<TResult, TGroup> groupSelector,
Func<IGrouping<TGroup, TResult>, TReturn> selector
);
Is that possible?
Here is a solution to what I think you asked for.
First, the base repository. I've created a base repository because I hope you will not expose this madness to the application but to the repositories only.
abstract class BaseRepo<TEntity>
{
// If you're using Entity Framework, this method could
// be implemented here instead.
protected abstract IQueryable<TEntity> Entities { get; }
protected IList<TReturn> GetAllPaged<TResult, TKey, TGroup, TReturn>(
List<Expression<Func<TEntity, bool>>> predicates,
Expression<Func<TEntity, TResult>> firstSelector,
Expression<Func<TResult, TKey>> orderSelector,
Func<TResult, TGroup> groupSelector,
Func<IGrouping<TGroup, TResult>, TReturn> selector)
{
return predicates
.Aggregate(Entities, (current, predicate) => current.Where(predicate))
.Select(firstSelector)
.OrderBy(orderSelector)
.GroupBy(groupSelector)
.Select(selector)
.ToList();
}
}
Then the implementation.
class HorseRepo : BaseRepo<Horse>
{
// This will of course be some data source
protected override IQueryable<Horse> Entities
{
get
{
return new List<Horse> {
new Horse { Id = 1, Name = "Mr Horse", Color = "Brown" },
new Horse { Id = 2, Name = "Mrs Horse", Color = "White" },
new Horse { Id = 3, Name = "Jr Horse", Color = "White" },
new Horse { Id = 4, Name = "Sr Horse", Color = "Black" },
new Horse { Id = 5, Name = "Dr Horse", Color = "Brown" },
}.AsQueryable();
}
}
// This is what I think you should expose to the application
// This is the usage of the expression fest above.
public IEnumerable<GroupedHorses> GetGroupedByColor() {
return horseRepo.GetAllPaged(
new List<Expression<Func<Horse, bool>>> {
h => h.Name != string.Empty,
h => h.Id > 0
},
h => new HorseShape { Id = h.Id, Name = h.Name, Color = h.Color },
hs => hs.Name,
hs => hs.Color,
g => new GroupedHorses
{
Color = g.Key,
Horses = g.ToList()
}
);
}
}
Some classes needed:
class GroupedHorses
{
public string Color { get; set; }
public IList<HorseShape> Horses { get; set; }
}
class HorseShape
{
public int Id { get; set; }
public string Name { get; set; }
public string Color { get; set; }
}
// Define other methods and classes here
class Horse
{
public int Id { get; set; }
public string Name { get; set; }
public string Color { get; set; }
public string UninterestingProperty { get; set; }
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With