I have following query:
var accounts =
from account in context.Accounts
from guranteer in account.Gurantors
select new AccountsReport
{
CreditRegistryId = account.CreditRegistryId,
AccountNumber = account.AccountNo,
DateOpened = account.DateOpened,
};
return accounts.AsEnumerable()
.Select((account, index) => new AccountsReport()
{
RecordNumber = FormattedRowNumber(account, index + 1),
CreditRegistryId = account.CreditRegistryId,
AccountNumber = FormattedAccountNumber(account.AccountType, account.AccountNumber)}).OrderByDescending(c => c.StateChangeDate);
It works fine except one problem and that is it returns records number in reverse order like 3, 2,1 because of .OrderByDescending(c => c.StateChangeDate);
Can I show the record number in ascendeing order while keeping the records in descending order.
Please suggest.
Thanks
Try using OrderBy on RecordNumber and then ThenByDescending on StateChangeDate
.OrderBy(c => c.RecordNumber).ThenByDescending(c => c.StateChangeDate);
Related
I'm using ASP.NET Core 3.1. I have written some code like the following and now I want to get the result of these two queries that has the same size and iterate over each one of them and divide their element and store the result in a list. But now the problem is in my zip method, I can not specify exactly which attribute of each query I want to divide.
var mytotal = _context.Apiapp.GroupBy(o => new
{
Month = o.ApiRequestDate.Substring(4, 2),
Year = o.ApiRequestDate.Substring(0, 4)
}).Select(g => new
{
Month = g.Key.Month,
Year = g.Key.Year,
Total = g.Count()
}).OrderByDescending(a => a.Year).ThenByDescending(a => a.Month).ToList();
var numerator = from t1 in _context.Apiapp
join t2 in _context.ApiAppHistory on t1.Id equals t2.ApiApplicantId
join t3 in _context.EntityType on t2.LastReqStatus equals t3.Id
where t1.IsDeleted == false && t1.LastRequestStatus == t2.Id && t3.Name == "granted"
group new { Year = t1.ApiRequestDate.Substring(0, 4), Month = t1.ApiRequestDate.Substring(4, 2) }
by new { t2.LastReqStatus } into g
select new
{
Year = g.Max(n => n.Year),
Month = g.Max(n => n.Month),
GrantedCount = g.Count()
};
var GrantedReqStatus = numerator.ToList();
var GrantedAccessPercent = new List<Double>();
//-------------------------------------------------------
var res = mytotal.Zip(GrantedReqStatus, (total, GrantedCount) => new { Num = total, Denum = GrantedCount });
foreach(var r in res)
{
GrantedAccessPercent.Add(r.Num/r.Denum);
}
Here inside the body of foreach, r.Num and r.Denum is unknown! I appreciate of any help to fix the error.
The Num and DemNum in the Zip function represent objects for the first and second collection, that contains Month,Year and Total for the total object and Month,Year and GrantedCount for the grantedCount object.
You could use total.Total and grantedCount.GrantedCount to get numbers, like the following code:
var res = mytotal.Zip(GrantedReqStatus, (total, grantedCount) => new { Num = total.Total, Denum = grantedCount.GrantedCount });
foreach(var r in res)
{
GrantedAccessPercent.Add(Math.Round(r.Num / (double)r.DemNum, 2));
}
Note that, to divide int1/int2 you need to cast int2 to double, Will give the expected result, and you can use also Math.Round to specify numbers after comma.
I hope this help you fix the issue.
Please consider this simple class
public class SEANCE
{
int ID_SEANCE {get;set;}
DateTime SEA_DATE {get;set;}
}
It's for a fitness management app, the SEANCE class is the session table for the members.
Here's my starting query to show the number of the sessions grouped by day Hour
var lst = ctx.SEANCES
.GroupBy(o => o.SEA_DATE.Hour)
.Select(g => new ChartData()
{
DT = new DateTime(2017, 01, 01, g.Key, 0, 0),
VALUE = g.Count()
});
return lst.OrderBy(a => a.DT).ToList();
as you can see, it returns the total number of sessions grouped by hour.
What I want instead is the average number of sessions by day and grouped by hour, and that's where I am a little lost :p
here what i mean
for example at 18, 1500 is corresponding to the total number of sessions at that time.
what i want instead is the average number by day
hope it make sense now :)
ctx.SEANCES.Count() / lst.Count(), but that seems like database source so better to use the result:
var groups = ctx.SEANCES
.GroupBy(s => s.SEA_DATE.Hour)
.OrderBy(g => g.Key)
.Select(g => new ChartData()
{
DT = g.First().SEA_DATE,
VALUE = g.Count()
})
.ToList();
var averageByHour = groups.Average(c => c.VALUE);
var averageByDay = groups.GroupBy(s => s.DT.Day).Average(g => g.Sum(c => c.VALUE));
I need to return all records (items) that has a part (X) so I can use that in a group or .GroupBy afterwards
Using this summary data:
ItemName PartName
1 A
1 B
2 A
3 C
So Item1 has two parts (A,B), etc...
I need a LINQ query that will
- find all items that have part A (i.e items 1 and 2)
- return all rows for all these items
1 A
1 B
2 A
Notice that the end result returned the row (1 B) because Item1 has PartA and so I need to get back all rows for Item1.
I was looking at something like:
let items = from data in summary where data.PartName == A select new { data.ItemName } // to get all the items I need
But then, now that I have that list I need to use it to get all the rows for all items listed, and I can't seem to figure it out ...
Actual Source Code (for reference):
NOTE:
Recipe = ITEM
Ingredient = PART
(I was just trying to make it simpler)
ViewFullRecipeGrouping = (
from data in ViewRecipeSummary
group data by data.RecipeName into recipeGroup
let fullIngredientGroups = recipeGroup.GroupBy(x => x.IngredientName)
select new ViewFullRecipe()
{
RecipeName = recipeGroup.Key,
RecipeIngredients = (
from ingredientGroup in fullIngredientGroups
select new GroupIngredient()
{
IngredientName = ingredientGroup.Key
}
).ToList(),
ViewGroupRecipes = (
from data in ViewRecipeSummary
// this is where I am looking to add the new logic to define something I can then use within the next select statement that has the right data based on the information I got earlier in this query.
let a = ViewRecipeSummary.GroupBy(x => x.RecipeName)
.Where(g => g.Any(x => x.IngredientName == recipeGroup.Key))
.Select(g => new ViewRecipe()
{
RecipeName = g.Key,
IngredientName = g.Select(x => x.IngredientName)
})
select new GroupRecipe()
{
// use the new stuff here
}).ToList(),
}).ToList();
Any help would be much appreciated.
Thanks,
I believe this does what you want:
var data = /* enumerable containing rows in your table */;
var part = "X";
var items = new HashSet<int>(data
.Where(x => x.PartName == part)
.Select(x => x.ItemName));
var query = data.Where(x => items.Contains(x.ItemName));
If I understand your comment at the end, I believe this also does what you want:
var query = data
.GroupBy(x => x.ItemName)
.Where(g => g.Any(x => x.PartName == part))
.Select(g => new
{
ItemName = g.Key,
PartNames = g.Select(x => x.PartName)
});
I have a requirement to sort a list by 1) the number of times a distinct item appears and then 2) if the count of two distinct rows is the same, the most recently used date of that group.
My group by function and sorting by count is working without the date:
(from x in data
group x by new { x.Col1, x.Col2, x.Col3}
into g
let count = g.Count()
select new
{
g.Key.Col1,
g.Key.Col2,
g.Key.Col3,
count
}).OrderByDescending(x => x.count)
However, I have been unable to successfully add the date sort. I was trying to add the date column as an aggregate in the group by expression, but that doesn't work.
(from x in data
group x by new { x.Col1, x.Col2, x.Col3, MaxDate = x.CreatedDateTime.Max()}
into g
let count = g.Count()
select new
{
g.Key.Col1,
g.Key.Col2,
g.Key.Col3,
count,
g.Key.MaxDate
}).OrderByDescending(x => x.count).ThenByDescending(x => x.MaxDate)
I get why it doesn't work, I just can't think of another route to add the secondary sort. Any ideas are appreciated!
This is what you're looking for (I think)
from x in data
group x by new { x.Col1, x.Col2, x.Col3}
into g
let count = g.Count()
select new
{
g.Key.Col1,
g.Key.Col2,
g.Key.Col3,
MaxDate = g.Select(x => x.CreatedDateTime)
.OrderByDescending(d => d).FirstOrDefault(),
count
}).OrderByDescending(x => x.count).ThenByDescending(x => x.MaxDate)
How about:
var ordered = Elev8SnaTowelTables
.GroupBy(x => new { x.Col1, x.Col2, x.Col3 })
.OrderByDescending(g => g.Count())
.ThenByDescending(g => g.Max(x => x.CreatedDateTime));
I have a list of objects. E.g. List<coin> where they contain a string(denom) and int(year).
If the list contains:
"Quarter", 1954
"Quarter", 1990
"Penny", 1925
"Nickel", 1900
"Nickel", 2000
How can I get a resultant list where it contains the unique values with just the most recent year? E.g.:
"Quarter", 1990
"Penny", 1925
"Nickel", 2000
You can do this by grouping by name, then either ordering and taking the first result, or by using something like MaxBy from MoreLINQ:
var query = coins.GroupBy(x => x.Name)
.Select(g => g.MaxBy(x => x.Year));
or
var query = coins.GroupBy(x => x.Name)
.Select(g => g.OrderByDescending(x => x.Year).First());
You can do this using group by like:
var query = from coin in myList
group coin by coin.Name into grouped
select new
{
Name = grouped.Key
Year = grouped.Max(x => x.Year)
};
For another sample like this, check out "max - grouped" in the 101 Linq examples: http://msdn.microsoft.com/en-us/vcsharp/aa336747#maxGrouped
var coins = new Coin[] { ... };
var recentCoins =
from coin in coins
group coin by coin.Denom into g
select new
{
Denom = g.Key,
MostRecentYear = g.Max(c => c.Year)
};