I have a business object structured like this:
Country has States, State has Cities
So Country[2].States[7].Cities[5].Name would be New York
Ok, I need to get a list of all the Country objects which have at least 1 City.IsNice == true
How do I get that?
var selectedCountries =
countries.Where(
co => co.States.Any(
s => s.Cities.Any(
ci => ci.IsNice)));
Another option :
var selectedCountries =
countries.Where(
co => co.States.SelectMany(s => s.Cities).Any(
ci => ci.IsNice));
var result = (from country in db.Countries
from state in country.States
from city in state.Cities
where city.IsNice
select county).Distinct();
I would do it in one of two ways:
var selectedCountries = from country in countries
from state in country.States
from city in state.Cities
where city.IsNice
select country;
or
var selectedCountries =
countries.Where(country =>
country.States.FirstOrDefault(state =>
state.Cities.FirstOrDefault(city =>
city.IsNice) != null) != null);
var result = Countries
.SelectMany(a => a.States)
.SelectMany(b => b.Cities)
.Where(b => b.IsNice == true)
.ToList();
Related
I'm wondered I have a table with IDs and a version and a remove field. I d like to return the the top 20 records grouped by ID and for ech ID take only the highest version unless remove is set then ignore removed records.
Then return a descending record set.
There are a few ways todo it with Linq but I wonder is there a most efficient way, are there patterns to avoid?.
...
.OrderByDescending(x=>x.id)
.GroupBy(x=>x.id)
.SelectMany(y=>y.Where(x=>x.Version == y.Max(y=>y.Version)))
.Where(x=>x.Remove=false)
.Take(20)
One of then possible workarounds when using EF Core. I'm calling it workaround because with SQL and Window functions we can create more effective query.
var itemsQuery = ctx.SomeTable
.Where(x => x.Remove = false);
var query =
from d in itemsQuery.Select(d => new { d.id }).Distinct()
from x in itemsQuery.Where(x => d.Id == x.Id)
.OrderByDescending(x => x.Version)
.Take(1)
select x;
query = query.Take(20);
Similar queries when using EF Core 6:
var query = ctx.SomeTable
.Where(x => x.Remove = false)
.GroupBy(x => x.Id)
.Take(20)
.SelectMany(g => g.OrderByDescending(x => x.Version).Take(1));
var query = ctx.SomeTable
.Where(x => x.Remove = false)
.GroupBy(x => x.Id)
.Select(g => g.OrderByDescending(x => x.Version).First());
.Take(20);
I have a table with 3 columns.
And I would like to present a table with this structure:
Can someone show me how to do this with Lambda expressions?
So far I've only gotten the result if I only wanted to show one column:
var sum_data = _context.HechosFinanza
.Where(x => x.Product.Sale_Type == "Cash Sale")
.GroupBy(x => x.Product.Product_Name)
.Select(x => Product { Tienda = x.Key, Total = x.Sum(s =>
s.sales_amount) });
I don't know if something like this may be possible (no idea really, just trying to figure it out):
var sum_data = _context.HechosFinanza
// I remove there where condition from here
.GroupBy(x => x.Product.Product_Name)
// And I add the where condition in each sum
.Select(x => Product { Tienda = x.Key,
TotalCash = x.Sum(s => s.sales_amount).Where(s => s.Product.Sale_Type == "Cash Sale"),
TotalCredit = x.Sum(s => s.sales_amount).Where(s.Product.Sale_Type == "Credit Sale")
});
Uhm, well. It turns out I was really close.
Just had to put the 'Where' statement before.
Answer:
var sum_data = _context.HechosFinanza
// I remove there where condition from here
.GroupBy(x => x.Product.Product_Name)
// And I add the where condition in each sum
.Select(x => Product { Tienda = x.Key,
TotalCash = x.Where(s => s.Product.Sale_Type == "Cash Sale").Sum(s => s.sales_amount),
TotalCredit = x.Where(s.Product.Sale_Type == "Credit Sale") .Sum(s => s.sales_amount)
});
And done.
List<branch_rating> ObjRat = new List<branch_rating>();
ObjRat=(_Context.branch_rating
.GroupBy(a => a.restaurant_branch_id)
.Select(a => new { rating = a.Sum(b => b.rating), Name = a.Key })
.OrderByDescending(a => a.rating)).ToList();
I tried by putting query in var variable and then adding in object.
Below picture shows the error.
I want to get data from branch_rating table having four columns, I also tried by using var and then adding list data one by one in object.
It will be better if you make a custom class like DOTopResturant which includes data members branch_rating,branch_id and then make a object of type DOTopResturant , add every item in variable q into that object.
List<branch_rating> ObjRat = new List<branch_rating>();
ObjRat = _Context.branch_rating.ToList();
var q = (_Context.branch_rating
.GroupBy(a => a.restaurant_branch_id)
.Select(a => new { branch_rating = a.Sum(b => b.rating), branch_id = a.Key })
.OrderByDescending(a => a.branch_rating)).ToList();
List<DOTopResturant> ObjTopRes = new List<DOTopResturant>();
foreach (var item in q)
{
ObjTopRes.Add(new DOTopResturant() { branch_id = Convert.ToInt32(item.branch_id), branch_rating = Convert.ToInt32(item.branch_rating) });
}
return ObjTopRes;
Just read and understand what the error describes :
your are trying to convert an anonymous type (with 2 properties Name and Rating) to another object type branch_rating.
You have 2 solutions :
work with the anonymous type (using var) :
var ObjRat=(_Context.branch_rating
.GroupBy(a => a.restaurant_branch_id)
.Select(a => new { Rating = a.Sum(b => b.rating), Name = a.Key })
.OrderByDescending(a => a.rating))
.ToList();
And then, in your code, just access to Rating and Name properties of your list members.
work with your type defined branch_rating, by using it in your Select, and use the appropriate constructor.
List<branch_rating> ObjRat = new List<branch_rating>();
ObjRat=(_Context.branch_rating
.GroupBy(a => a.restaurant_branch_id)
.Select(a => new branch_rating() { <Your branch_rating properties assignments here> })
.OrderByDescending(a => a.rating)).ToList();
If your branch_rating object does not have an empty constructor, call the correct constructor with good arguments in the Select.
Change select (third row in the picture) to:
.Select(a => new DOTopRestaurant {rating = a.Sum(b => b.rating), Name = a.Key})
Delete the declaration of ObjRat and use var:
var ObjRat=(_Context.branch_rating
.GroupBy(a => a.restaurant_branch_id)
.Select(a => new { rating = a.Sum(b => b.rating), Name = a.Key })
.OrderByDescending(a => a.rating))
.ToList();
Your list is a list of the anonymous type not of type branch_rating.
If you want to convert it to branch_rating use another Select to create a new branch_rating(...) passing the appropriate parameters to the constructor.
PS You should also look at .NET naming conventions.
I have table structure like
Product {List<Cost> Costs}
Cost{List<Invoice> Invoices, Product product}
Invoice{bool isIncluded}
Need a query to get all Products which has any Cost for which none of invoice is included (isIncluded=false for all)
I tried something like:
Product pro= null;
Product p = null;
var costQuery = QueryOver.Of<Cost>()
.JoinAlias(c => c.Product, () => p)
.Where(() => p.Id == pro.Id)
.WhereNot(c=>c.Invoices.Any(i=>i.IsIncluded))
.Select(c => c.Id);
var query = CurrentSession.QueryOver<Product>(() => pro)
.WithSubquery.WhereExists(costQuery);
Use of 'Any' in query errors out:
Unrecognised method call: System.Linq.Enumerable:Boolean
Any[Invoice](System.Collections.Generic.IEnumerable1[Trigger.StageGate.Services.BusinessEntities.Invoice],
System.Func2[Trigger.StageGate.Services.BusinessEntities.Invoice,System.Boolean])
try:
var costQuery = QueryOver.Of<Cost>()
.JoinAlias(c => c.Product, () => p)
.Where(() => p.Id == pro.Id)
.JoinQueryOver<Invoice>(c => c.Invoices)
.WhereNot(i => i.IsIncluded)
.Select(c => c.Id);
how can i show null or empty fields in last by apply Orderby:
here is my code.
Var movies = _db.Movies.Orderby(c => c.Category).ThenBy(n => n.Name)
If I understand your question correctly:
Var movies = _db.Movies
.OrderBy(c => c.Category==null?1:0)
.Thenby(c => c.Category).ThenBy(n => n.Name)