list contains an ID in linq - c#

I am trying to find a linq query so I can write it in an if statement.
Pseudo code:
IDList is a list of ints List< int >
if (IDList.Contains (Object.Id)) Do something
but I can't seem to work out what need.
In none-linq this works:
foreach(int id in IDList )
{
if (id == Object.Id)
break;
}
but I want it as one line if possible.
I first tried this:
IDList.Contains(Object.Id);
but this throws a compile error
I'm wondering should it be one of these two?
IDList.Any(id => id == Object.Id)
or
IDList.Exists(id => id == Object.Id);
I don't completely understand how the lambdas and things work or the difference between andy and exists so I'm not sure if I'm along the wrong line?

You can simply do this:
if (MyList.Any(c => c.Id == MyObject.Id)) { }
Assuming that MyList is an IEnumerable<T> (or anything that derives from IEnumerable<T>) where T is an object that has a property named Id of the same type of the property Id on the MyObject instance.

IDList.Any(id => id == Object.Id)
Is ok, it will return you true if at least one element, that satisfies your predicate, exists.

Related

LINQ can't convert to 'int?'

I am trying to sort by multiple criteria whereas I have to return the Id of the most expensive car and if there are multiple cars with the same value then return the newest car based on manufacture date.
public int? Exercise7demo(List<Car> cars)
{
if (cars == null)
{
return null;
}
else
{
List<Car> sorted = cars
.OrderByDescending( x => x.SuggestedRetailPrice )
.ThenBy( x => x.ManufacturedDate )
.ToList();
return sorted.ID;
}
}
It is getting stuck because I can't wrap my head around why it won't return "sorted". I says specifically "Can't explicitly convert type System.Collections.Generic.List to 'int?'
What am I missing? Please note that I can't change the public type to make this work, I have thought of that but this is part of an online demo course I am doing so this is the setup.
EDIT: I should clarify that ID is original defined and is part of the public int? statement (sorry terminology might be off here). For some reason, If I try to recall .ID in the return statement, it says it is not defined. Is that because of my List sorted = cars statement?
Thanks!
After the sorting criteria, you have applied ToList() which means you'd still get a List<Car>, not an int.
You'd have to change that to:
return sorted.FirstOrDefault().ID;
You might also want to check for any null value, so:
return sorted.FirstOfDefault()?.ID;
You can simply do:
return cars.OrderByDescending(x => x.SuggestedRetailPrice).ThenBy(x => x.ManufacturedDate).FirstOrDefault().ID;
You do not need to convert to list. Even more, it may impact the performance (from MSDN):
The ToList(IEnumerable) method forces immediate query evaluation and returns a List that contains the query results.
So, the suggested way solves your problem and keep the evaluation lazy.
your sorted is a list. In order to return top item you can use first which will return first value.
Try like this
return sorted.First().ID;
Sorted is a list of card, but you only want the id of the first car of the list. So use : return sorted.First().ID
It will return the ID of the first car of the list.

Linq: Removing Group By but still get its items?

Just some details. Get Records is a variable where it contains the results of my stored procedure. Now, what I want to ask is what if I want to remove the group by function but I still want to get the key and items? Is there a way to do it?
var sortResCinema = GetRecords.Where(x => test2.branch == x.Bbranch && test.movieName == x.MovieName && x.MovieName != null)
.GroupBy(x => x.MovieName,
(key, elements) =>
new
{
Id = key,
Items = elements.ToList()
}).ToList();
There's no need for GroupBy here since you are looking for a specific movieName.
I guess you wanted something like this:
var sortResCinema = GetRecords.Where(x => test2.branch == x.Bbranch && test.movieName == x.MovieName).ToList();
You can replace the GroupBy with a Select. The Select statement can be used to alter the type of the results returned, which is what you appear to want to do. Should work with exactly the same syntax as the second parameter. So replace "GroupBy" with "Select" and remove the first argument. The key and elements properties that are being used in the GroupBy statement are internal to that function so you'd need to work out what function you want to replace these by, for instance the key might be x.MovieName.

Lambda expression to return one result for each distinct value in list

I currently have a large list of a class object and I am currently using the following lambda function to return elements that meet the condition.
var call = callList.Where(i => i.ApplicationID == 001).ToList();
This will return a list of objects that all have an id of 001.
I am now curious as to what different ApplicationIDs there are. So I would like a lambda function that will look into this list and return a list where all the element have a different ApplicationID but only fetches one of those.
If i understand your question you can try:
var list = callList.GroupBy(x => x.ApplicationID).Select(x => x.First()).ToList();
So if you have a list like:
AppID:1, AppID:1, AppID:2, AppID:2, AppID:3, AppID:3
Will return:
AppID:1 AppID:2 AppID:3
You can use either First or FirstOrDefault to get back one result
var call = callList.First(i => i.ApplicationID == 001);
If no call exisrs with an ApplicationID of 001 this will throw an exception. If this may be expected consider using:
var call = callList.FirstOrDefault(i => i.ApplicationID == 001);
Here null will be returned if no such call exists and you can handle accordingly in you code.
To find out what other ApplicationId's exist you can query:
var Ids = callList.Where(i => i.ApplicationID != 001).Select(i => i.ApplicationID).Distinct();
You are saying
I am now curious as to what different ApplicationIDs there are. So I
would like a lambda function that will look into this list and return
a list where all the element have a different ApplicationID but only
fetches one of those.
I would suggest that is never something you'd actually want. You either don't care about the elements, you care about all of them, or you care about a specific one. There are few (none?) situations where you care about a random one from the list.
Without knowing about which specific one you care, I can't give you a solution for that version. Allesandro has given you a solution for the random one.
When you only care about the distinct ID's you would end up with
callList.Select(c => c.ApplicationID).Distinct()
which just gives you all ApplicationIDs.
if you care about all of them, you'd end up with
callList.GroupBy(c => c.ApplicationID)
this will give you an IEnumerable<IGrouping<String, Thingy>> (where Thingy is the type of whatever the type of elements of callList is.)
This means you now have a collection of ApplicationID -> collection of Thingy's. For each distinct ApplicationID you'll have a "List" (actually IEnumerable) of every element that has that ApplicationID
If you care for the Thingy of that - for example - has the lowest value of property Foo you would want
callList.GroupBy(c => c.ApplicationID)
.Select(group => group.OrderBy(thingy => thingy.Foo).First()))
here you first Group them by ApplicationID, and then for each list of thingies with the sample ApplicationID you Select the first one of them if you Order them by Foo
There is a way to use the Distinct in the query, but it makes you take care about the values equality. Let's assume your type is called CallClass and try:
class CallClass : IEqualityComparer<CallClass>
{
public int ApplicationId { get; set; }
//other properties etc.
public bool Equals(CallClass x, CallClass y)
{
return x.ApplicationId == y.ApplicationId;
}
public int GetHashCode(CallClass obj)
{
return obj.GetHashCode();
}
}
Now you're able to query values distinctly:
var call = callList.Distinct().ToList();

Unknown Select(?) of System Data Entity DbSet

Is something like this possible? I am getting the below error.
db.SomeTable.Add(new SomeTable()
{
GuidId = Guid.NewGuid(),
Name = db.AnotherTable.Select(x => x.Name.Where(x.Id == localVariable.Id))
}
);
db.SaveChanges();
Unknown Select(?) of System Data Entity DbSet
Select returns an IEnumerable, not an individual record. You would needed to add a .First() call to grab just one record. Entity Framework thinks you're trying to put a list into a single field.
Furthermore, your use of Where() is incorrect. Where also returns an IEnumerable, and can only be applied on to an IEnumerable. Think of it as a way to filter a list.
Here's how to do what I think you're asking for:
Name = db.AnotherTable.First(x => x.id == someId).Name
I think what you want is this:
Name = db.AnotherTable
.First(x => x.Id == localVariable.Id)
.Name;
The steps of this are:
Go into list of items in AnotherTable
Find the first item where the Id of the item is equal to localVariable.Id
Set your variable equal to the Name property of the item you found
You can also use FirstOrDefault(), Single(), and SingleOrDefault().

C# How do i return iGrouping to a list using lambda expression

I am using entity framework to do this , i have this lambda expression :
public IList<Model.questionhint> GetRecordsPlease(int listTask, int listActivity)
{
IList<Model.questionhint> lstRecords = context.questionhints.ToList();
return lstRecords.GroupBy(x => new {
x.QuestionNo,
x.ActivityID,
x.TaskID })
.Where(a => a.Key.TaskID == listTask
&& a.Key.ActivityID == listActivity)
.ToList();
}
but it says :
Cannot implicitly convert type
'System.Collections.Generic.List<System.Linq.IGrouping<AnonymousType#1,iStellar.Model.questionhint>>'
to 'System.Collections.Generic.IList<iStellar.Model.questionhint>'. An
explicit conversion exists (are you missing a cast?)
This codes is in my CRUD class file named DAOQuestionHint .
How do i return this because i need to call it in my xaml.cs ( code behind ) like this :
private DAO.DAOQuestionHint qh = new DAO.DAOQuestionHint();
IList<Model.questionhint> lstQuestionHints = qh.GetRecordsPlease(taskID, activityID);
This is how my database table looks like :
what i wanted is to group records of the same activityID , taskID and questionNo together in a line , now every record is seperated line by line like this :
i want it to be like
I [answer] to have a nap every afternoon
The sun [answer] not move round the earth.
So i tried to use alternative in code behind by using for loop but that doesn't work perfectly if there are 3 or more records of the same activityID , taskID and questionNo , so i tot i need to group them in the query first .
It seems to me that you don't need to group at all - you just need to filter. Unless you really have more than one hint per question (with the same task and activity), you just need:
public IList<Model.questionhint> GetRecordsPlease(int listTask, int listActivity)
{
return context.questionhints
.Where(a => a.TaskID == listTask && a.ActivityID == listActivity)
.ToList();
}
Note that unlike your current code, this will perform the filtering in the database, rather than pulling the whole table to the client and then grouping/filtering. You need to be aware that any time you use context.SomeTable.ToList(), that will pull the entire contents of that table.
I'd also strongly suggest that you change your model to use type names which follow .NET naming conventions, so QuestionHint instead of questionhint.
(Finally, I'd remove the Please from the method name - computers don't need you to be polite in your naming like this.)
EDIT: If you really do want groups, you need to change the return value. For example, you could just return a sequence of groups:
public IList<IGrouping<int, Model.questionhint>>
GetRecordsPlease(int listTask, int listActivity)
{
return context.questionhints
.Where(a => a.TaskID == listTask && a.ActivityID == listActivity)
.ToList()
.GroupBy(a => a.QuestionNo)
.ToList();
}
I've deliberately called ToList() here before the grouping and then again afterwards so that the data is fetched once and you can iterate over those groups however you like without it going back to the database. (It's possible that just the final ToList would be enough, but I wouldn't like to say for sure.)

Categories

Resources