The idea is. I have items which initially I would like to order by DateCreated. Last created shows first in a grid.
But I have some items which have LastDateTime. If LastDateTime < DateTime.Now I need to show them after all most current items. So they have to be at the end.
Example of needed output results:
# Item DateCreated LastDate
--------------------------------------------------------------------------
1. Item 1 07-11-2011 07-29-2011
2. Item 2 07-10-2011 07-29-2011
3. Item 3 07-09-2011 07-29-2011
4. Item 4 07-08-2011 07-29-2011
5. Item 5 07-16-2011 07-18-2011
6. Item 6 07-13-2011 07-15-2011
7. Item 7 07-11-2011 07-12-2011
Tables:
-------------------------------------------------
ID (PK) Item (string) DateCreated (DateTime)
Table 2
-------------------------------------------------
DayID (PK) ID (FK) DateTimeUtc (DateTime)
Here is example of my linq query. It shows all items with last day < date time now at the end. but it doesn't show properly order by created date.
return (from i in _entity.Items
join d in _entity.Days
on i.ID equals d.ID into leftJoinTable
where i.ID == 123
select new
{
i.ID,
i.Item,
LastDate = leftJoinTable.OrderByDescending(a => a.DayID)
.Select(a => a.DateTimeUtc)
.FirstOrDefault()
}).Distinct()
.OrderByDescending(x => x.ID)
.ThenBy(x=>x.LastDate)
.ToList();
Try ordering by DayID in your last OrderByDescending.
return (from i in _entity.Items
join d in _entity.Days
on i.ID equals d.ID into leftJoinTable
where i.ID == 123
select new
{
i.ID,
i.Item,
LastDate = leftJoinTable.OrderByDescending(a => a.DayID)
.Select(a => a.DateTimeUtc)
.FirstOrDefault()
}).Distinct()
.OrderByDescending(x => x.ID) // You're ordering by ID first
.ThenBy(x=>x.LastDate)
.ToList();
EDIT: Ah sorry didn't see that. My best guess is that since your ordering by ID first which would almost cancel out the LastDate ordering. You said you need them ordered by LastDate first correct? Does it matter on the order of the ID's? If not just .OrderByDescending(x => x.LastDate)
Related
Hello every one I have a data as follows
Item Qty Type
1 2 Purchase
1 3 Sales
1 8 Return
2 5 Purchase
2 4 Sales
2 5 Return
Now I have a requirement of getting quantity of each item by Subtracting Sales and Return with Purchase
And my final output would be
item Qty
1 -9
2 -4
Note : To get quantity: Qty => (Purchase Qty - SalesQty - Return Qty) eg: (2-3-8)
So how can I write this query on LINQ or in SQL
SQL Query:
SELECT Item, SUM(CASE Type WHEN 'Purchase' THEN Qty ELSE -Qty END) AS Qty
FROM Table
GROUP BY Item
LINQ:
Items
.GroupBy(p => p.Item)
.Select(p => new
{
Item = p.Key,
Qty = p.Sum(x => x.Type == "Purchase" ? x.Qty : -x.Qty)
});
If you are using LINQ to SQL, you can do:
var ans = from i in src
group i by i.Item into ig
let PurchaseQty = ig.Where(i => i.Type == "Purchase").Sum(i => i.Qty)
let SalesQty = ig.Where(i => i.Type == "Sales").Sum(i => i.Qty)
let ReturnQty = ig.Where(i => i.Type == "Return").Sum(i => i.Qty)
select new {
Item = ig.Key,
Qty = PurchaseQty - SalesQty - ReturnQty
};
If you are using LINQ to EF 2.2, it may work but will do the grouping client side. If you are using EF 3.x, good luck!
I am trying to select multiple table values using linq to sql
This is the code I wrote:
var query = (from p in context.Personel
join y in context.PerLanguage on p.ID equals y.ID
where p.Resign == false && p.KGBT > new DateTime(2012,1,15)
select new{ p.ID,p.NameSurname, y.EarnedDate,y.Degree}).ToList();
PerLanguage has a foreignkey "ID" to Personel. So PerLanguage table can have 2 or more data that has the same ID. I am expecting this piece of code to return me a List of items having the "last" entered Language data of different people.
What is the best way to do it?
try the following query.. basically we make the join, get the flat results, group it by id and descending sort the results within an ID and select the first record in every grouped result.
var results = context.Personel.Where(p => !p.Resign && p.KGBT > new
DateTime(2012,1,15)).Join(context.PerLanguage, p => p.ID, pl => pl.ID, (p, pl) =>
new { p.ID, p.NameSurname, pl.EarnedDate, pl.Degree }).GroupBy(r => r.ID)
.Select(g => g.OrderByDescending(r => r.EarnedDate).First()).ToList();
Consider the following list of dates
ID NAME DATE
1 Mary 01-01-1901
2 Mary 01-01-1901
3 Mary 01-01-1901
4 Mary 01-01-1901
5 Lucy 01-01-1951
6 Peter 01-01-1961
The above is a list ORDERED BY DATE. Hence in the database it is not represented like so.
I am trying to fetch the next record in the list BY DATE. What I am doing is, retrieving the list of
persons from the database, then ordering by Date and then by ID. What is happening is that the
IDs returned are always the same:
Next Record -> 2 -> Next Record -> 1 -> Next record 2
and so on... It seems I am stuck on the first 2 records. I am using LINQ-to-SQL
Below is the code I am using to achieve this
string newID = dx.Persons
.AsEnumerable()
.ToList()
.Where(
x => x.DOB.CompareTo(newConvertedValue) == 0 && x.Id > currentID
||
x.DOB.CompareTo(newConvertedValue) > 0 && x.Id != currentID)
.OrderBy(x => x.DOB)
.ThenBy(x => x.Id)
.Select(x => x.Id.ToString(CultureInfo.InvariantCulture))
.First();
For me it makes no sense to order the list after specifying the Where conditions, but when i tried to modify
the statement I got a no element in sequence exception.
Please note that the variables stated above have the following meanings:
newConvertedvalue = date of birth of the currently displayed record
currentID = ID of the currently displayed record.
I have tried using different solutions but I cannot seem to find a way to solve this.
I have implemented similar methods to sort and fetch next records for columns containing integers and strings,
which are working fine (Also thanks to the contribution from this great website).
But this column containing Dates is giving me a hard time.
Thanks for reading.
Use
var Ids = dx.Persons
.AsEnumerable()
.ToList()
.Where(x => x.DOB.CompareTo(newConvertedValue) == 0 && x.Id > currentID
||
x.DOB.CompareTo(newConvertedValue) > 0 && x.Id != currentID)
.OrderBy(x => x.DOB)
.ThenBy(x => x.Id)
.Select(x => new { ID = Id, Date = DOB })
.ToList();
Ids.ForEach(x => Console.WriteLine(x.ID));
I have the data structure
For each item there is a record of it's price on a certain date in each currency. I need to create a query that returns the most current price for each currency.
This query works, but returns multiple Amounts for currency ID 1. It should only return 3 records, 7,8 and 9 as these represent the most up to date prices in all currencies for this item.
var q = (from c in db.tblStoreItemPrices where c.ItemID == ID select new { c.CurrencyID, c.Amount });
Please ignore all ordering and assume that records are randomly ordered.
This should work:
db.tblStoreItemPrices
.Where(c => c.ItemID == ID)
.GroupBy(c => c.CurrencyID)
.Select(g => g.OrderByDescending(c => c.Date).First())
.Select(c => new { c.CurrencyID, c.Amount });
Explanation:
Select rows for the specific ItemID
Group by CurrencyID
From within each currency group select the row that has the most recent date (leaving one row for for each CurrencyID in the result set)
Pull out the information you want from these rows
The LINQ query below is working fine but I need to tweak it a bit.
I want all the records in the file grouped by recordId (a customer number) and then ordered by, in descending order, the date. I'm getting the grouping and the dates are in descending order. Now, here comes the tweaking.
I want the groups to be sorted, in ascending order, by recordId. Currently, the groups are sorted by the date, or so it seems. I tried adding a .OrderBy after the .GroupBy and couldn't get that to work at all.
Last, I want to .take(x) records where x is dependent on some other factors. Basically, the .take(x) will return the most-recent x records. I tried placing a .take(x) in various places and I wasn't getting the correct results.
var recipients = File.ReadAllLines(path)
.Select (record => record.Split('|'))
.Select (tokens => new
{
FirstName = tokens[2],
LastName = tokens[4],
recordId = tokens[13],
date = Convert.ToDateTime(tokens[17])
}
)
.OrderByDescending (m => m.date)
.GroupBy (m => m.recordId)
.Dump();
Edit #1 -
recordId is not unique. There may / will likely be multiple records with the same recordId. recordId is actually a customer number.
The output will be a resultset with first name, last name, date, and recordId. Depending on several factors, there many be 1 to 5 records returned for each recordId.
Edit #2 -
The .Take(x) is for the recordId. Each recordId may have multiple rows. For now, let's assume I want the most recent date for each recordId. (select top(1) when sorted by date descending)
Edit #3 -
The following query generates the following results. Note each recordId only produces 1 row in the output (this is okay) and it appears it is the most recent date. I haven't thouroughly checked this yet.
Now, how do I sort, in ascending order, by recordId?
var recipients = File.ReadAllLines(path)
.Select (record => record.Split('|'))
.Select (tokens => new
{
FirstName = tokens[2],
LastName = tokens[4],
recordId = Convert.ToInt32(tokens[13]),
date = Convert.ToDateTime(tokens[17])
}
)
.GroupBy (m => m.recordId)
.OrderByDescending (m => m.Max (x => x.date ) )
.Select (m => m.First () )
.Dump();
FirstName LastName recordId date
X X 2531334 3/11/2011 12:00:00 AM
X X 1443809 10/18/2001 12:00:00 AM
X X 2570897 3/10/2011 12:00:00 AM
X X 1960526 3/10/2011 12:00:00 AM
X X 2475293 3/10/2011 12:00:00 AM
X X 2601783 3/10/2011 12:00:00 AM
X X 2581844 3/6/2011 12:00:00 AM
X X 1773430 3/3/2011 12:00:00 AM
X X 1723271 2/4/2003 12:00:00 AM
X X 1341886 2/28/2011 12:00:00 AM
X X 1427818 11/15/1986 12:00:00 AM
You can't that easily order by a field which is not part of the group by fields. You get a list for each group. This means, you get a list of date for each recordId.
You could order by Max(date) or Min(date).
Or you could group by recordId and date, and order by date.
order by most recent date:
.GroupBy (m => m.recordId)
// take the most recent date in the group
.OrderByDescending (m => m.Max(x => x.date))
.SelectMany(x => x.First
The Take part is another question. You could just add Take(x) to the expression, then you get this number of groups.
Edit:
For a kind of select top(1):
.GroupBy (m => m.recordId)
// take the most recent date in the group
.OrderByDescending (m => m.Max(x => x.date))
// take the first of each group, which is the most recent
.Select(x => x.First())
// you got the most recent record of each recordId
// and you can take a certain number of it.
.Take(x);
snipped I had before in my answer, you won't need it according to your question as it is now:
// create a separate group for each unique date and recordId
.GroupBy (m => m.date, m => m.recordId)
.OrderByDescending (m => m.Key)
This seems very similar to your other question - Reading a delimted file using LINQ
I don't believe you want to use Group here at all - I believe instead that you want to use OrderBy and ThenBy - something like:
var recipients = File.ReadAllLines(path)
.Select (record => record.Split('|'))
.Select (tokens => new
{
FirstName = tokens[2],
LastName = tokens[4],
recordId = tokens[13],
date = Convert.ToDateTime(tokens[17])
}
)
.OrderBy (m => m.recordId)
.ThenByDescending (m => m.date)
.Dump();
For a simple Take... you can just add this .Take(N) just before the Dump()
However, I'm not sure this is what you are looking for? Can you clarify your question?
just add
.OrderBy( g=> g.Key);
after your grouping. This will order your groupings by RecordId ascending.
Last, I want to .take(x) records where
x is dependent on some other factors.
Basically, the .take(x) will return
the most-recent x records.
If you mean by "the most recent" by date, why would you want to group by RecordId in the first place - just order by date descending:
..
.OrderByDescending (m => m.date)
.Take(x)
.Dump();
If you just want to get the top x records in the order established by the grouping though you could do the following:
...
.GroupBy (m => m.recordId)
.SelectMany(s => s)
.Take(x)
.Dump();
If you want something like the first 3 for each group, then I think you need to use a nested query like:
var recipients = File.ReadAllLines(path)
.Select(record => record.Split('|'))
.Select(tokens => new
{
FirstName = tokens[2],
LastName = tokens[4],
RecordId = tokens[13],
Date = Convert.ToDateTime(tokens[17])
}
)
.GroupBy(m => m.RecordId)
.Select(grouped => new
{
Id = grouped.Key,
First3 = grouped.OrderByDescending(x => x.Date).Take(3)
}
.Dump();
and if you want this flattened into a record list then you can use SelectMany:
var recipients = var recipients = File.ReadAllLines(path)
.Select(record => record.Split('|'))
.Select(tokens => new
{
FirstName = tokens[2],
LastName = tokens[4],
RecordId = tokens[13],
Date = Convert.ToDateTime(tokens[17])
}
)
.GroupBy(m => m.RecordId)
.Select(grouped => grouped.OrderByDescending(x => x.Date).Take(3))
.SelectMany(item => item)
.Dump();