var query = TableNoTracking;
query = query
.Include(r => r.UserRoles).ThenInclude(o => o.Role)
.Include(c => c.Photos.Where(x => x.IsMain))
.Include(w => w.Wallets);
my sort part is like below and I want handle sorting dynamically
if (!string.IsNullOrWhiteSpace(filterUser.SortBy))
{
switch (filterUser.Reverse)
{
//reverse
case true:
switch (filterUser.SortBy)
{
case UserNavigationPropsForSort.InventorySum:
query = query.OrderByDescending(x => x.Wallets.Select(y => y.Inventory).Sum());
break;
case UserNavigationPropsForSort.InterMoneySum:
query = query.OrderByDescending(x => x.Wallets.Select(y => y.InterMoney).Sum());
break;
case UserNavigationPropsForSort.ExitMoneySum:
query = query.OrderByDescending(x => x.Wallets.Select(y => y.ExitMoney).Sum());
break;
case UserNavigationPropsForSort.OnExitMoneySum:
query = query.OrderByDescending(x => x.Wallets.Select(y => y.OnExitMoney).Sum());
break;
}
break;
case false:
switch (filterUser.SortBy)
{
case UserNavigationPropsForSort.InventorySum:
query = query.OrderBy(x => x.Wallets.Select(y => y.Inventory).Sum());
break;
case UserNavigationPropsForSort.InterMoneySum:
query = query.OrderBy(x => x.Wallets.Select(y => y.InterMoney).Sum());
break;
case UserNavigationPropsForSort.ExitMoneySum:
query = query.OrderBy(x => x.Wallets.Select(y => y.ExitMoney).Sum());
break;
case UserNavigationPropsForSort.OnExitMoneySum:
query = query.OrderBy(x => x.Wallets.Select(y => y.OnExitMoney).Sum());
break;
}
break;
}
}
I include several entities, now I want to order this query dynamically based on included properties, for example inventory in wallet. i tried dynamic linq library but it dont work for this situation;
How can I do this?
CodePudding user response:
I'm not entirely sure it's possible to do it fully dynamic without setting up a mapping between UserNavigationPropsForSort
and a Wallet
property.
- Unless you want to get into expression tree building, which I suspect is overkill for what you're actually trying to do. If not, refer to docs here: https://docs.microsoft.com/en-us/dotnet/csharp/expression-trees-building
What I've done is made your code a bit more concise and expandable:
var query = TableNoTracking;
query = query
.Include(r => r.UserRoles).ThenInclude(o => o.Role)
.Include(c => c.Photos.Where(x => x.IsMain))
.Include(w => w.Wallets);
if (!string.IsNullOrWhiteSpace(filterUser.SortBy.ToString()))
{
Func<Wallet, decimal> sortByToProperty = filterUser.SortBy switch
{
UserNavigationPropsForSort.InventorySum => w => w.Inventory,
UserNavigationPropsForSort.InterMoneySum => w => w.InterMoney,
UserNavigationPropsForSort.ExitMoneySum => w => w.ExitMoney,
UserNavigationPropsForSort.OnExitMoneySum => w => w.OnExitMoney,
_ => throw new ArgumentOutOfRangeException()
};
query = filterUser.Reverse
? query.OrderByDescending(x => x.Wallets.Select(sortByToProperty).Sum())
: query.OrderBy(x => x.Wallets.Select(sortByToProperty).Sum());
}
If, at any point, you want to add more properties to sort by, you can expand the sortByToProperty
switch.
Please let me know if this is what you meant.
CodePudding user response:
Credit to @nbokmans and @Svyatoslav Danyliv. I used Expression instead of Func and now code work.
if (!string.IsNullOrWhiteSpace(filterUser.SortBy))
{
if (filterUser.SortableProperties.Any(x =>
string.Equals(x, filterUser.SortBy, StringComparison.CurrentCultureIgnoreCase)))
{
Expression<Func<User, int>> exp = filterUser.SortBy switch
{
UserNavigationPropsForSort.InventorySum => w => w.Wallets.Select(x => x.Inventory).Sum(),
UserNavigationPropsForSort.InterMoneySum => w => w.Wallets.Select(x => x.InterMoney).Sum(),
UserNavigationPropsForSort.ExitMoneySum => w => w.Wallets.Select(x => x.ExitMoney).Sum(),
UserNavigationPropsForSort.OnExitMoneySum => w => w.Wallets.Select(x => x.OnExitMoney).Sum(),
_ => throw new ArgumentOutOfRangeException()
};
query = filterUser.Reverse ? query.OrderByDescending(exp) : query.OrderBy(exp);
}
}