LINQ expression to filter - c#

I have the following LINQ expression where I am fetching Courses, Students that belong to that Course, then the School's where the Student's goes to. The following LINQ expression works fine.
However, I need to further, filter it where I need to get Students with the City == 'Colarado'. How can I alter the following LINQ to my use case.
_dbContext.Courses
.Where(c => c.Id == Id)
.Include(c => c.Students)
.ThenInclude(c => c.Schools)
.OrderByDescending(c => c.Id)
.ToListAsync();

If you need all courses and only filter students - since EF Core 5.0 you can use filtered include:
_dbContext.Courses
.Where(c => c.Id == Id)
.Include(c => c.Students.Where(s => s.City == "Colarado"))
.ThenInclude(c => c.Schools)
.OrderByDescending(c => c.Id)
.ToListAsync();

You can do the filter in the Where method.
_dbContext.Courses
.Where(c => c.Id == Id && c.Students.All(s => s.City == "Colarado"))
.Include(c => c.Students)
.ThenInclude(c => c.Schools)
.OrderByDescending(c => c.Id)
.ToListAsync();

Related

GroupBy in subquery with MAX() in C#

I Have this code. It works fine but when I have two same maximal values it appear 2 times. So I need to use OrderBy. But I dont know how. Thanks for any help.
IQueryable<PerformanceRealization> pr = _context.PerformanceRealization
.Where(u => u.Deadline == _context.PerformanceRealization
.Where(x => x.GroupRealizationId == u.GroupRealizationId)
.Max(x => x.Deadline)
)
.Select(u => u);
Here is the SQL code with GROUP BY
SELECT PR.GroupRealizationId
FROM Stores.PerformanceRealization PR
LEFT JOIN Stores.GroupRealization ON Stores.GroupRealization.Id = PR.GroupRealizationId
WHERE PR.Deadline = (SELECT MAX(Deadline)
FROM Stores.PerformanceRealization PR2
WHERE PR.GroupRealizationId = PR2.GroupRealizationId)
GROUP BY PR.GroupRealizationId
You can select the first object from the group
IQueryable<PerformanceRealization> pr2 = pr
.GroupBy(x => x.GroupRealizationId)
.Select(g => g.First());
If you need a specific object from the group, then you can order by another column
IQueryable<PerformanceRealization> pr2 = pr
.GroupBy(x => x.GroupRealizationId)
.Select(g => g.OrderBy(x => x.SomeColumn).First());
for SomeColumn having the smallest value. For the greatest value, use OderByDescending instead.
Of course, you can integrate this approach into the first query:
IQueryable<PerformanceRealization> pr = _context.PerformanceRealization
.Where(u => u.Deadline == _context.PerformanceRealization
.Where(x => x.GroupRealizationId == u.GroupRealizationId)
.Max(x => x.Deadline)
)
.GroupBy(x => x.GroupRealizationId)
.Select(g => g.OrderBy(x => x.SomeColumn).First());
Note, you don't need to have a Select at the end like .Select(u => u). Since it has no effect, you can just drop it.
If your EF Core version cannot handle it (as revealed in a comment), then transition to LINQ-to-Objects with AsEnumerable(), but do the filtering in EF Core to minimize the number of records sent to the front-end:
IQueryable<PerformanceRealization> pr = _context.PerformanceRealization
.Where(u => u.Deadline == _context.PerformanceRealization
.Where(x => x.GroupRealizationId == u.GroupRealizationId)
.Max(x => x.Deadline)
)
.AsEnumerable() // <===== transition from LINQ-to-EF-Core to LINQ-to-Objects
.GroupBy(x => x.GroupRealizationId)
.Select(g => g.OrderBy(x => x.SomeColumn).First());

OrderBy deletes object property

I have the following code:
var test = _fitDbContext.MvLatestTestResult
.Include(r => r.LastTest)
.Include(r => r.LastTest.Testrun)
.Include(r => r.LastTest.Testrunconfig)
.Where(r => r.LastTest.Testrunconfig.Started.Value.Hour >= 0 && r.LastTest.Testrunconfig.Started.Value.Hour < 6)
.Where(r => r.LastTest.Testrun.Userc == "build")
.Where(r => r.ProductId == productId)
.GroupBy(r => r.LastTest.Testrunconfig.Started.Value.Date)
.OrderByDescending(r => r.Key.Date)
.Take(3)
.ToDictionary(group => group.Key, group => group.GroupBy(r => r.Configfilename));
Variable test looks like this:
You can see that LastTest is null. If I remove .OrderByDescending(r => r.Key.Date), it contains value.
Why does OrderByDescending remove LastTest value?
EDIT
Interesting thing I just found out. If I change order of GroupBy and OrderBy, everything works as expected. The problem is that OrderBy is executed with all records and takes a long time.
var test = _fitDbContext.MvLatestTestResult
.Include(r => r.LastTest)
.Include(r => r.LastTest.Testrun)
.Include(r => r.LastTest.Testrunconfig)
.Where(r => r.LastTest.Testrunconfig.Started.Value.Hour >= 0 && r.LastTest.Testrunconfig.Started.Value.Hour < 6)
.Where(r => r.LastTest.Testrun.Userc == "build")
.Where(r => r.ProductId == productId)
.OrderByDescending(r => r.Key.Date)
.GroupBy(r => r.LastTest.Testrunconfig.Started.Value.Date)
.Take(3)
.ToDictionary(group => group.Key, group => group.GroupBy(r => r.Configfilename));

Select from many tables - Entity Framework

I have that table construction and code sample:
var Tasks = db.Users
.Where(t => t.Id == 1)
.Where(t => t.Tables.Where(a => a.Id == 1)))
.Select(a => a.Tasks.Select(a => a.Tasks.Text));
This code don't work, how can I get Tasks.Text when I using many where questions?
Thanks

Lambda Expression to filter Included Entities

I have this query,
var productCategories = _dbContext
.Set<ProductCategory>()
.Include(x => x.ProductInCategories)
.ThenInclude(x => x.Product)
.ThenInclude(x => x.ProductMetadatas)
.Where(x => x.Active)
.ToList();
But, I can't filter products in this query. I just want to have the Active Products. Any Help will be appreciated.

nHibernate Subquery-WhereAll displays "not a delegate type"-error

I am trying to create a nHibernate-Query with a subquery following this blog-entry.
My working SQL looks like this:
SELECT *
FROM Product
WHERE Id IN (
SELECT p.Id
FROM Product AS p
INNER JOIN ProductSupplier AS ps
ON ps.ProductId LIKE p.Id
WHERE ps.SupplierProductNumber LIKE '102.02-7100'
GROUP BY p.Id
);
I have to group by the Id because multiple suppliers can have the same productNumber for the same product.
My nHibernate looks as following:
query.WithSubquery.WhereAll(
p => p.Id ==
QueryOver.Of<Product>()
.JoinAlias(x => x.Suppliers, () => productSupplierAlias)
.Where(() => productSupplierAlias.Product.Id == productAlias.Id)
.Where(() => productSupplierAlias.SupplierProductNumber == searchtext)
.Select(p => p.Id));
But my .Select(p => p.Id) displays
cannot convert lambda expression to type 'nHibernate.Creterian.IProjection[]' because it is not a delegate type
I don't think you should be using WhereAll in this case.
Does this work:
query.WithSubquery.WhereProperty(p => p.Id)
.In(QueryOver.Of<Product>()
.JoinAlias(x => x.Suppliers, () => productSupplierAlias)
.Where(() => productSupplierAlias.Product.Id == productAlias.Id)
.Where(() => productSupplierAlias.SupplierProductNumber == searchtext)
.Select(p => p.Id)
);

Categories

Resources