Linq include only max row - c#

I'm pulling items from a table that i'm including another table.
When including, there is likely multiple rows belonging to that item in the included table but I only want to include the row that contains the max value of a column.
items.AddRange(db.AuctionItems
.Include(f => f.AuctionBids.Max().Bid)
.OrderBy(x => x.Item));
Also tried
items.AddRange(db.AuctionItems
.Include(f => f.AuctionBids.Max(y => y.Bid))
.OrderBy(x => x.Item));
Error
The Include path expression must refer to a navigation property defined on the type. Use dotted paths for reference navigation properties and the Select operator for collection navigation properties.
Added info
Table AuctionItems
ID
Name
.....
Table AuctionBids
ID
ItemID
Bid
....
So I want to pull all items and include only the row that contains the highest bid for that item.

You may do the following:
db.AuctionItems
.Select(s => new{ai = s, bid = s.AuctionBids.OrderByDescending(o => o.Bid).FirstOrDefault()})
.AsEnumerable()
.Select(s => s.ai)
Using this approach you are loading only required AuctionBids into context and EF will do the mapping to appropriate AuctionItems for you.

Related

How to get list of latest entry for each parent using entity framework?

I have a table named "Children" which has columns like "Id", "ParentId", "Description", "LastUpdate" etc. I want to query a list which will have distinct rows for each parentId and I want those rows latest according to the value of the "LastUpdate" column which is a DateTime.
What is the simplest way to achieve this?
I have tried something like this:
var latestList = _context.Children.where(x => !x.Deleted).OrderByDescending(x => x.LastUpdate).DistinctBy(x => x.ParentId).ToList();
But this couldn't be translated into sql. So what else can I do now?
If I understand your query correctly, for each Parent you want the Child that has the latest LastUpdate:
var latestList = _context.Children
.Where(x => !x.Deleted)
.GroupBy(x => x.ParentId)
.Select(g => g.MaxBy(x => x.LastUpdate))
.ToList();
You can order the children before .ToList();

Using LINQ to filter through ID's based on if a certain column is flagged

I have a database that holds InvoiceID and a column boolean flag called Corrected. I'm trying to use LINQ to filter whether the database contains these IDs (IDs from another list) but if the Corrected flag is set to true, it would not add that ID.
This is simple enough but the issue I am having is that there might be the same object ID more than once in my table and if any of them have the Corrected flag I would like to skip them all.
So far my code only skips the ones that have the flag set to true. So for example, I might have 8 records with the same ID but only 4 of them have the Corrected flag. Ideally I would skip this ID all together. The below code will only skip 4 and still include the other 4.
var uncorrectedIDs = _context.Table1.SelectMany(y => y.Invoices
.Where(z => invoiceIDsInPeriod.Contains(z.InvoiceId)
&& y.Invoices.Any(w => !w.Corrected))));
How can I adapt this to the above specification? Thanks
GroupBy could be one approach
var notCorrected =
_context.Table1
.SelectMany(table => table.Invoices.Where(i => period.Contains(i.InvoiceId))
.GroupBy(invoice => invoice.Id)
.Where(group => group.Any(invoice => invoice.Corrected) == false)
.SelectMany(group => group)
.ToList();

"Jump" over deleted rows

My datatable contains a large number of empty rows that are deleted. I'm using the following code to split the table into several new tables based on the value of Printers, however I need to add contingency for those deleted rows. How can I add this contingency within the following statement?
List<DataTable> dtCollection = dt.AsEnumerable()
.GroupBy(row => row.Field<string>("Printers"))
.Select(g => g.CopyToDataTable())
.ToList();`
My theory is that I should be able to create some sort of bool within GroupBy, but I'm not sure how to approach this.
If you want to filter out those rows which were deleted, then you can use simple Where statement which checks state of a row:
List<DataTable> dtCollection = dt.AsEnumerable()
.Where(row => row.RowState != DataRowState.Deleted)
.GroupBy(row => row.Field<string>("Printers"))
.Select(g => g.CopyToDataTable())
.ToList();

Linq to List: Is there a way to include all the columns after applying a groupby on list

I have a list that is getting its values from the database and then this is converted to a datatable, but before doing that i want to apply groupby on the list and get all the columns instead of just a key and a value. After a new list is created using groupby datatable does not show all the columns instead it has only two columns which says capacity and count.
var groupedResults = Results.GroupBy(x => x.PROJECT_ID)
.Select(y => y.ToList())
.ToList();
Results is a list which contains around 14 columns or keys in this case with all project related properties project name, id etc. When I use Results and convert that to datatable I do not have any issue but when I use groupedResults list as shown above and convert that to a datatable it does not have all the 14 columns and an exception is raised as column not found. Is there a way to select all the keys as in original list.
Thank you
Have you tried wwith something like:
var groupedResults = Results.GroupBy(x => new {x.PROJECT_ID, obj = x})
.Select(y => y.Key.obj.ToList())
.ToList();
Try something like this
var e = Results.GroupBy(x => x.PROJECT_ID) .Select(y =>new { ProjectId = y.Key,
Count=y.Count()})
.Join(Results,x=>x.ProjectId,y=>y.PROJECT_ID,(x1,y1) => new
{x1.ProjectId,x1.Count,y1.Col1,y1.Col2 /* Add all columns you need */} )
.ToList();

Issue with many-to-many query with linq to entities

I've got a table
Application
ApplicationID,
NAme
ApplicationSteps
AplicationStepID,
AplicationID,
StepID
ApplicationStepCriterias
ApplicationStepID,
CriteriaID
So I've got one SelectedCriteriaID - a user choose from a dropdown one criteria and he wants all the applications which has this SelectedCriteriaID in the table ApplicationStepCriterias
I tried
var ds = context.Applications
.Where(a => a.ApplicationSteps
.Select(x=>x.ApplicationStepCriterias
.Select(t=>t.CriteriaId))
.Contains(SelectesdCriteria));
But as I have as result IEnumerable<IEnumerable<int>> I cannot use Contains
Just I get a list of all the CriteriaIds for each ApplicationStep(also a sequence). Just I cannot think of way to get in one list all the CriteriIds.
First, let me try to get the names right. This is not a pure many-to-many association, because the junction class is part of the class model. It is what I unofficially call a 1-n-1 association. So you have
Application -< ApplicationSteps >- ApplicationStepCriterias
I'd strongly recommend to use singular names for your classes ...
Application -< ApplicationStep >- ApplicationStepCriterion
... so you can use plural for collection property names without getting confused.
If I'm right so far, you query should be
context.Applications
.Where(a => a.ApplicationSteps
.Any(x => selectedCriteria
.Contains(x.ApplicationStepCriterion.CriteriaId));
(and I'd also prefer CriterionId, probably referring to a Criterion class)
You may try something like this:
var applicationStepIds = context.ApplicationStepCriterias
.Where(i => i.CriteriaID == selectedCriteria)
.Select(i => i.ApplicationStepID)
.Distinct();
var applicationIds = context.ApplicationSteps
.Where(i => applicationStepIds.Contains(i.AplicationStepID))
.Select(i => i.AplicationID)
.Distinct();
var result = context.Applications.Where(i => applicationIds.Contains(i.ApplicationId));

Categories

Resources