This question already has an answer here:
linq select items from child collection
(1 answer)
Closed 6 years ago.
I am not sure if the word "Simplifiying" is suitable in this context or not? But, I have a Linq Query lile below :
result.FIRSTOBJECT
.Select(x => x.SECONDOBJECT
.Select(y => y.THIRDOBJECT
.Where(j => j.Key.Contains("Something"))));
And the result object I get is something like above screen-shot.
My Question: Is there a way that I can make this result to NOT be so nested?
So you want to flatten the sequences? Then you can use SelectMany:
var allMathingThirdObjects = result.FIRSTOBJECT
.SelectMany(x => x.SECONDOBJECT.SelectMany(y => y.THIRDOBJECT))
.Where(j => j.Key.Contains("Something"));
You can loop the result in a foreach or create a collection(f.e. with allMathingThirdObjects.ToList()) or select the first one:
var firstMatchingThird = allMathingThirdObjects.FirstOrDefault(); // null if no match
or select the Key property into a single string:
string allMatchingThirdKeys = String.Join(", ", allMathingThirdObjects.Select(j => j.Key));
Use SelectMany instead
result = result.FIRSTOBJECT
.SelectMany(x => x.SECONDOBJECT
.SelectMany(y => y.THIRDOBJECT
.Where(j => j.Key.Contains("Something"))));
var finalresult = result.FirstOrDefault();
Related
This question already has answers here:
Linq version of SQL "IN" statement
(6 answers)
Closed 4 years ago.
[Sorry if it is a duplicate]
I couldn't find properly solution, so I decided to ask a question.
I have an object companies which returns list of elements.
I would like to write a query which will select these all CompanyId which we have in our list. I don't want to select only one record by using FirstOrDefault().
Example:
var companiesSummary = _context.Company
.Where(c => c.CompanyId == companies.Select(cs => cs.ID))
.Include(country => country.Country)
How can I cope with it? Do you have any ideas?
Select the ids of the companies from your in-memory list and then pass that into the query in the where method:
var ids = companies.Select(cs => cs.ID).ToList();
var companiesSummary =
_context.Company
.Where(c => ids.contains(c.ID))
.Include(country => country.Country)
Assuming your companies contains a list of objects with an ID property you want to compare to Company.CompanyId, your query should look like
int[] ids = companies.Select(cs => cs.ID).ToArray();
var companiesSummary = _context.Company
.Where(c => ids.Contains(c.CompanyId))
.Include(company => company.Country);
var matchingCompanies = companies.Where(c => companyIds.Contains(c.Id))
Make companyIds a HashSet<T> for an efficient Contains.
This question already has answers here:
Create a list from two object lists with linq
(8 answers)
Closed 5 years ago.
I have 2 lists of string and I am merging them but selecting a specific column.
I managed to get it, but I am sure there is a better way:
public List<string> GetAll()
{
var i = _iRepository.GetAll().Select(x => x.Name).ToList();
var a = _aRepository.GetAll().Select(x => x.Name);
i.AddRange(a);
return i;
}
List<string> allNameList = _iRepository.GetAll()
.Select(x => x.Name)
.Concat(_aRepository.GetAll().Select(x => x.Name))
.ToList();
If you want to remove duplicates use Union instead of Concat.
Pull the string out of list one, and concatenate it to the list of string from list 2:
_iRepository.Select(x => x.Name).Concat(_aRepository.Select(x => x.Name)).ToList()
ps; I'm not sure how you have 2 lists of string - if _iRepository were a list of string, you wouldn't be able to select x.Name because a string doesn't have a .Name property! The lists are List<SomeObjectThatHasANameProperty>, surely.. ?
Shorter (assuming both GetAll() return the same type) :
return _iRepository.GetAll().Concat(_aRepository.GetAll()).Select(x => x.Name).ToList();
A bit more efficient (less memory allocations) if GetAll() returns a new list:
var list = _iRepository.GetAll();
list.AddRange(_aRepository.GetAll());
return list.ConvertAll(x => x.Name);
From this LINQ:
var inspectionItems = inspArchive.Select(x => x.InspectionItems);
I get this result in inspectionItems :
My question is how can I make using LINQ in elegant way to make from inspectionItems result above one array distincted by Id.
Like that:
You want the SelectMany() LINQ method:
var inspectionItems = inspArchive.SelectMany(x => x.InspectionItems);
If you only want distinct items by a particular property, then you can either implement an equality comparer to see if your inspection classes are equal, then call .Distinct(myInspectionEqualityComparer) at the end of your method chain, or you can do this:
var distinctInspectionItems = inspArchive.SelectMany(x => x.InspectionItems)
.GroupBy(i => i.Id)
.Select(group => group.First());
Without seeing more of your code, I think you want to use SelectMany and Distinct ?
var inspectionItems = inspArchive.SelectMany(x => x.InspectionItems).Distinct();
The question is unclear, but check if this works for you:
var inspectionItems = inspArchive.SelectMany(x => x.InspectionItems)
.GroupBy(x => x.ID)
.Select(g => g.First())
.ToArray();
I cannot seem to combine 2 GroupBy statements in 1 linq expression..
For now i'm doing something like this:
double maxInvestment = 0;
foreach (var playerAction in TotalUserActions.GroupBy(p => p.Player))
{
var MaxInvestmentPerPlayer = playerAction.GroupBy(p => p.RoundId)
.Select(p => p.LastOrDefault())
.Sum(p=> p.BetSize);
if(MaxInvestmentPerPlayer > maxInvestment)
maxInvestment = MaxInvestmentPerPlayer;
}
What I would like to do is something like this...
double maxInvestment = TotalUserActions.GroupBy(p => p.Player)
.GroupBy(p => p.RoundId)
.Select(p => p.LastOrDefault())
.Sum(p=> p.BetSize);
But that wont work.. Can someone help me on this?
Thanks!
Looks like this is what you want, the key takeaway being the inner query is wrapped in an outer call to Select():
var maxInvestment = TotalUserActions.GroupBy(p => p.Player)
.Select(g => g.GroupBy(x => x.RoundId)
.Select(x => x.LastOrDefault())
.Sum(x => x.BetSize))
.Max();
I do question your use of LastOrDefault() though as, since you have not specified any ordering, you may as well use FirstOrDefault() and save the hassle of skipping to the last element.
This question already has answers here:
What is the linq equivalent to the SQL IN operator
(9 answers)
Closed 8 years ago.
Is there any "IN" keyword available in Linq to entities syntax ? I have a listbox where multiple items are added. I want to search for those items in db. My query looks like this:
var result = context.data_vault
.Where(d => d.STATE == lstStates.SelectedItem.Text).OrderBy(d=>d.dv_id)
.Skip(e.NewPageIndex * GridView1.PageSize)
.Take(GridView1.PageSize)
.ToList();
I want d => d.STATE == lstStates.Items. How to change it?
The code:
string[] arr = listview.Items
.Cast<ListItem>()
.Select(i => i.Text) // or .Value
.ToArray();
db.Where(d => arr.Contains(d.STATE);
should be translated into the query:
... WHERE STATE IN ('your', 'array', 'items')
Try this:
var result = context.data_vault
.Where(d => lstStates.Items.Contains(d.STATE)).OrderBy(d=>d.dv_id)
.Skip(e.NewPageIndex * GridView1.PageSize)
.Take(GridView1.PageSize)
.ToList();
Here,
lstStates is List<string>
You can try .Any() or .Contains() syntax
example something like this:
select d from context.Data
Where ListofIdsFromUI.Any(d.Id)
select d