i have a LINQ Query which is written in VB.NET:
foo = (From p In lOrder
Group By p.ItemCode Into Group = Sum(p.Quantity)
).ToDictionary(Function(x) x.ItemCode, Function(x) x.Group)
My problem is to translate the Sum. C# seems to not like it very well.
Can anybody help me translating this query?
thank you
Here's an exact translation of your LINQ query in C#:
var foo = lOrder.GroupBy(p => p.ItemCode,
(key, values) => new
{
ItemCode = key,
Group = values.Sum(v => v.Quantity)
})
.ToDictionary(x => x.ItemCode, x => x.Group);
If I understand correctly, you want to get a mapping between the item code to the cumulative quantity of the items under this code.
Given an IEnumerable named orders you can do the following:
var foo = from p in orders
group p by p.ItemCode into OrderGroupedByCode
select new { Code = OrderGroupedByCode.Key, Sum = OrderGroupedByCode.Sum(x => x.Quentity) };
This gives you an IEnumerable of anonymous objects the you can easily turn into a dictionaryif you want:
foo.ToDictionary(x => x.Code, x => x.Sum)
Related
I plan on using this in a subquery but can't figure out the correct syntax to translate the following query into LINQ:
select ChapterID, min(MeetingDate)
from ChapterMeeting
group by ChapterID
var query = myDataContext.ChapterMeeting
.GroupBy(cm => cm.ChapterID)
.Select(g => new {
g.Key,
MinMeetingDate = g.Min(cm => cm.MeetingDate)
});
Well, Amy beat me to it, but in case you wanted to see it with the "comprehension" syntax:
var q = (
from cm in context.ChapterMeeting
group cm by cm.ChapterID into cmg
select new {
ChapterID = cmg.Key,
FirstMeetingDate = cmg.Min(cm => cm.MeetingDate)});
How would you write a linq query with the following SQL statement. I've tried several methods referenced on stackoverflow but they either don't work with the EF version I'm using (EF core 3.5.1) or the DBMS (SQL Server).
select a.ProductID, a.DateTimeStamp, a.LastPrice
from Products a
where a.DateTimeStamp = (select max(DateTimeStamp) from Products where a.ProductID = ProductID)
For reference, a couple that I've tried (both get run-time errors).
var results = _context.Products
.GroupBy(s => s.ProductID)
.Select(s => s.OrderByDescending(x => x.DateTimeStamp).FirstOrDefault());
var results = _context.Products
.GroupBy(x => new { x.ProductID, x.DateTimeStamp })
.SelectMany(y => y.OrderByDescending(z => z.DateTimeStamp).Take(1))
Thanks!
I understand you would like to have a list of the latest prices of each products?
First of all I prefer to use group by option even over 1st query
select a.ProductID, a.DateTimeStamp, a.LastPrice
from Products a
where a.DateTimeStamp IN (select max(DateTimeStamp) from Products group by ProductID)
Later Linq:
var maxDateTimeStamps = _context.Products
.GroupBy(s => s.ProductID)
.Select(s => s.Max(x => x.DateTimeStamp)).ToArray();
var results = _context.Products.Where(s=>maxDateTimeStamps.Contains(s.DateTimeStamp));
-- all assuming that max datetime stamps are unique
I've managed to do it with the following which replicates the correlated sub query in the original post (other than using TOP and order by instead of the Max aggregate), though I feel like there must be a more elegant way to do this.
var results = from x
in _context.Products
where x.DateTimeStamp == (from y
in _context.Products
where y.ProductID == x.ProductID
orderby y.DateTimeStamp descending
select y.DateTimeStamp
).FirstOrDefault()
select x;
I prefer to break up these queries into IQueryable parts, do you can debug each "step".
Something like this:
IQueryable<ProductOrmEntity> pocoPerParentMaxUpdateDates =
entityDbContext.Products
//.Where(itm => itm.x == 1)/*if you need where */
.GroupBy(i => i.ProductID)
.Select(g => new ProductOrmEntity
{
ProductID = g.Key,
DateTimeStamp = g.Max(row => row.DateTimeStamp)
});
//// next line for debugging..do not leave in for production code
var temppocoPerParentMaxUpdateDates = pocoPerParentMaxUpdateDates.ToListAsync(CancellationToken.None);
IQueryable<ProductOrmEntity> filteredChildren =
from itm
in entityDbContext.Products
join pocoMaxUpdateDatePerParent in pocoPerParentMaxUpdateDates
on new { a = itm.DateTimeStamp, b = itm.ProductID }
equals
new { a = pocoMaxUpdateDatePerParent.DateTimeStamp, b = pocoMaxUpdateDatePerParent.ProductID }
// where
;
IEnumerable<ProductOrmEntity> hereIsWhatIWantItems = filteredChildren.ToListAsync(CancellationToken.None);
That last step, I am putting in an anonymous object. You can put the data in a "new ProductOrmEntity() { ProductID = pocoMaxUpdateDatePerParent.ProductID }...or you can get the FULL ProductOrmEntity object. Your original code, I don't know if getting all columns of the Product object is what you want, or only some of the columns of the object.
I have this query.
select distinct game_id, max(event_number) as LatestEvent from Source group by game_id
But I would like this converted to its Linq or Lambda equivalent and I havent found a way to do so properly. Can someone advise.
Thanks for your time.
var q = db.Table
.GroupBy(x => x.game_id)
.Select(g => new { game_id = g.Key, LatestEvent = g.Max(x => x.event_number) });
SELECT
[TimeStampDate]
,[User]
,count(*) as [Usage]
FROM [EFDP_Dev].[Admin].[AuditLog]
WHERE [target] = '995fc819-954a-49af-b056-387e11a8875d'
GROUP BY [Target], [User] ,[TimeStampDate]
ORDER BY [Target]
My database table has the columns User, TimeStampDate, and Target (which is a GUID).
I want to retrieve all items for each date for each user and display count of entries.
The above SQL query works. How can I convert it into LINQ to SQL? Am using EF 6.1 and my entity class in C# has all the above columns.
Create Filter basically returns an IQueryable of the entire AuditLogSet :
using (var filter = auditLogRepository.CreateFilter())
{
var query = filter.All
.Where(it => it.Target == '995fc819-954a-49af-b056-387e11a8875d')
.GroupBy(i => i.Target, i => i.User, i => i.TimeStamp);
audits = query.ToList();
}
Am not being allowed to group by on 3 columns in LINQ and I am also not sure how to select like the above SQL query with count. Fairly new to LINQ.
You need to specify the group by columns in an anonymous type like this:-
var query = filter.All
.Where(it => it.Target == '995fc819-954a-49af-b056-387e11a8875d')
.GroupBy(x => new { x.User, x.TimeStampDate })
.Select(x => new
{
TimeStampDate= x.Key.TimeStampDate,
User = x.Key.User,
Usage = x.Count()
}).ToList();
Many people find query syntax simpler and easier to read (this might not be the case, I don't know), here's the query syntax version anyway.
var res=(from it in filter.All
where it.Target=="995fc819-954a-49af-b056-387e11a8875d"
group it by new {it.Target, it.User, it.TimeStampDate} into g
orderby g.Key.Target
select new
{
TimeStampDate= g.Key.TimeStampDate,
User=g.Key.User,
Usage=g.Count()
});
EDIT: By the way you don't need to group by Target neither OrderBy, since is already filtered, I'm leaving the exact translation of the query though.
To use GroupBy you need to create an anonymous object like this:
filter.All
.Where(it => it.Target == '995fc819-954a-49af-b056-387e11a8875d')
.GroupBy(i => new { i.Target, i.User, i.TimeStamp });
It is unnecessary to group by target in your original SQL.
filter.All.Where( d => d.Target == "995fc819-954a-49af-b056-387e11a8875d")
.GroupBy(d => new {d.User ,d.TimeStampDate} )
.Select(d => new {
User = d.Key.User,
TimeStampDate = d.Key.TimeStampDate,
Usage = d.Count()
} );
I have the following block of code which works fine;
var boughtItemsToday = (from DBControl.MoneySpent
bought in BoughtItemDB.BoughtItems
select bought);
BoughtItems = new ObservableCollection<DBControl.MoneySpent>(boughtItemsToday);
It returns data from my MoneySpent table which includes ItemCategory, ItemAmount, ItemDateTime.
I want to change it to group by ItemCategory and ItemAmount so I can see where I am spending most of my money, so I created a GroupBy query, and ended up with this;
var finalQuery = boughtItemsToday.AsQueryable().GroupBy(category => category.ItemCategory);
BoughtItems = new ObservableCollection<DBControl.MoneySpent>(finalQuery);
Which gives me 2 errors;
Error 1 The best overloaded method match for 'System.Collections.ObjectModel.ObservableCollection.ObservableCollection(System.Collections.Generic.List)' has some invalid arguments
Error 2 Argument 1: cannot convert from 'System.Linq.IQueryable>' to 'System.Collections.Generic.List'
And this is where I'm stuck! How can I use the GroupBy and Sum aggregate function to get a list of my categories and the associated spend in 1 LINQ query?!
Any help/suggestions gratefully received.
Mark
.GroupBy(category => category.ItemCategory); returns an enumerable of IGrouping objects, where the key of each IGrouping is a distinct ItemCategory value, and the value is a list of MoneySpent objects. So, you won't be able to simply drop these groupings into an ObservableCollection as you're currently doing.
Instead, you probably want to Select each grouped result into a new MoneySpent object:
var finalQuery = boughtItemsToday
.GroupBy(category => category.ItemCategory)
.Select(grouping => new MoneySpent { ItemCategory = grouping.Key, ItemAmount = grouping.Sum(moneySpent => moneySpent.ItemAmount);
BoughtItems = new ObservableCollection<DBControl.MoneySpent>(finalQuery);
You can project each group to an anyonymous (or better yet create a new type for this) class with the properties you want:
var finalQuery = boughtItemsToday.GroupBy(category => category.ItemCategory);
.Select(g => new
{
ItemCategory = g.Key,
Cost = g.Sum(x => x.ItemAmount)
});
The AsQueryable() should not be needed at all since boughtItemsToday is an IQuerable anyway. You can also just combine the queries:
var finalQuery = BoughtItemDB.BoughtItems
.GroupBy(item => item.ItemCategory);
.Select(g => new
{
ItemCategory = g.Key,
Cost = g.Sum(x => x.ItemAmount)
});