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);
Related
This question already has answers here:
How to get first record in each group using Linq
(7 answers)
Closed 1 year ago.
What I try to achieve is the following: Filter the ProjektStatus with the where function, the group them by ProjektId. Order the group descending by StatusMonatJahr and then take the first element of each group and return it.
public IEnumerable<ProjektStatus> GetCurrentProjektStatus(Func<ProjektStatus, bool> where)
{
return this.db.ProjektStatus
.Where(where)
.GroupBy(x => x.ProjektId)
.Select(x =>
x.OrderByDescending(y => y.StatusMonatJahr))
.First();
}
Unfortunately, with this query I get the first whole group instead of the first element of each group.
What do I have to change to achieve this?
Thanks in advance
The code should return the first element in each group, not the content of the first group.
public IEnumerable<ProjektStatus> GetCurrentProjektStatus(Func<ProjektStatus, bool> where)
{
return this.db.ProjektStatus
.Where(where)
.GroupBy(x => x.ProjektId)
.Select(x => x.OrderByDescending(y => y.StatusMonatJahr).First());
}
Some remarks :
Language keyword should be avoided as variable name. Here it's about the where parameter. whereFunc is a good name.
The GroupBy, Select, OrderByDescending operations can be done remotely (server side), for that they should be called first. An other option is to do everything remotely, for that, the type of the whereFunc should be Expression<Func<ProjectStatus, bool>>.
Personal opinion: you should prefer to code in English, if your company doesn't do it, I feel bad for you.
Here is the result :
public IEnumerable<ProjectStatus> GetCurrentProjectStatuses(Func<ProjectStatus, bool> whereFunc)
{
return ProjectStatuses
.GroupBy(s => s.ProjectId)
.Select(g => g.OrderByDescending(s => s.MonthAndYear).First())
.AsEnumerable() // From now on the execution is done locally
.Where(whereFunc);
}
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 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();
This question already has answers here:
Integer Contains Using Linq
(2 answers)
Closed 6 years ago.
I want to have a search option where
1.user will type any letter that matches the name from database table.
This works smoothly.
string userinput = "hel"
List<string> queryResult = _myContext.Products
.Where(r => r.Name.Contains(userinput))
.Select(r => r.Name)
.ToList();
2. user will type any digit that should match the ID if that digit/digits exist in the ID it should give me a list of those ID
can i do something thing like that??
int queryId= 12;
_myContext.Products.Where(r => r.ID.contains(queryId)).Select(r => r.ID).ToList();
string queryId = "12";
List<string> queryResult = _myContext.Products
.Where(r => r.Id.Tostring().Contains(queryId))
.Select(r => r.ID)
.ToList();
This question already has answers here:
Multiple "order by" in LINQ
(7 answers)
Closed 8 years ago.
For example, I have an object with 3 properties: Name, Price and Description. I need to sort a collection of these objects. It's easy to sort by only one parameter:
var sortedList = ObjectCollection.OrderBy(x => x.Name).ToList();
But how to perform the sorting by 2 parameters (Name and Price). For example, I need to get a list like that:
ItemName1 $100 SomeDescription
ItemName1 $200 AnotherDescription
ItemName1 $250 AnotherDescription
ItemName2 $20 AnotherDescription
ItemName2 $40 Description
ItemName3 $100 Description
and so on. So, the main key is a Name, but if there are several items with the same name then the second key is the price. How to do this?
Use the ThenBy extension, as it does not override previously used OrderBy calls.
var sortedList = ObjectCollection.OrderBy(x => x.Name).ThenBy(x => x.Price).ToList();
You need to use ThenBy() using linq
ObjectCollection.OrderBy(x => x.Name).ThenBy(x => x.Price).ToList();
Use Enumerable.ThenBy:
var sortedList = ObjectCollection.OrderBy(x => x.Name).ThenBy(x => x.Description).ToList();
var sortedList = ObjectCollection.OrderBy(x => x.Name).ThenBy(x => x.SecondPropertyToOrderBy).ToList();
You can chain the OrderBy or OrderByDescending like this. I Hope this helps
You can use Linq:
ObjectCollection.OrderBy(x => x.Name).
ThenBy(x => x.Price).ToList();
If you can't use Linq, you can write a custom comparator.