Use IN operator in LINQ - c#

I have List<Candidate> Candidates, List<Seat> Seats
The Model defined as shown below
public class Seat
{
public string CollegeId { get; set; }
public bool isFilled { get; set; }
public string SeatType { get; set; }
public string RollNumber { get; set; }
}
public class Candidate
{
public string RollNumber { get; set; }
public bool isAllotted { get; set; }
public string Quota { get; set; }
public int CandidateRank { get; set; }
public List<OptionPriority> SeatingPriorities { get; set; }
}
public class OptionPriority
{
public string CollegeId { get; set; }
public int PriorityRank { get; set; }
}
I need to filter List<Seat> from List<Seat> Seats where Seats.CollegeId IN List of CollegeID in SeatingPriorities.

// same as EXISTS
Seats.Where(s => SeatingPriorities.Any(sp => sp.CollegeId == s.CollegeId))
Also you can join seatings with seatings priorities:
// same as INNER JOIN
var prioritySeats = from s in Seats
join sp in SeatingPriorities
on s.CollegeId equals sp.CollegeId
select s;
NOTE: Both of queries above will not generate IN clause if you will execute them in LINQ to SQL or LINQ to Entities. IN is generated when you use Contains method of primitive types list:
var ids = SeatingPriorities.Select(sp => sp.CollegeId).ToList();
// same as IN
var prioritySeats = Seats.Where(s => ids.Contains(s.CollegeId));

var results = source.Where(x => SeatingPriorities.Contains(x.CollegeId)).ToList();

You can use Enumerable.Contains to find out the matches like you do with in
var result = lstSeats.Where(s=>SeatingPriorities.Contains(s.CollegeId));

Use Contains to achieve IN functionality in LINQ

You could use Any:
seats.Where(s => SeatingPriorities.Any(i => i.Id == s.CollegeId))
Since Contains only accepts an instance to compare (along with a possible IEqualityComparer<T>), which won't work if OptionPriority isn't an comparable to CollegeId (i.e. a string).

Related

Comparing Arrays LINQ

How can I compare to array in linq and get all elements where there is at least one intersection?
Example:
selectes = {1,5,7}
Bands[0].SongsID {1,9}
Bands[1].SongsID {5,6}
Bands[2].SongsID {4,6}
I need to select Bands[0] and Bands[1].
I tried this:
var selectes2 = Bands.Where(t => t.SongsID.Intersect(selectes));
Bands class:
public class Band
{
public int ID { get; set; }
public string Name { get; set; }
public DateTime YearOfCreate { get; set; }
public string Country { get; set; }
public int[] SongsID { get; set; }
}
var selectes2 = Bands.Where(t => t.SongsID.Intersect(selectes).Any());
Assuming you mean to select any band that has any song ID that matches your list of ids, you could accomplish that with this:
var matchingBands = Bands.Where(band => band.SongsID.Any(selectes.Contains));

Distinct on multiple fields

I Have a List of some Properties as Model
public class AnswerList {
public int ID { get; set; }
public int? Schedule_ID { get; set; }
public int? SubItemID { get; set; }
public string SubItemName { get; set; }
public string ItemName { get; set; }
public string Answer { get; set; }
public string Remarks { get; set; }
public string Remarks_Flag { get; set; }
public string Lattitude { get; set; }
public string Longitude { get; set; }
public DateTime? Load_Date { get; set; }
}
I was getting list of Distinct Sub Items from this List
List<string> sub_item_list = AnswerList.Select(x => x.SubItemName).Distinct().ToList();
Now I want data in different format as per below class
public class SubItemList {
public string ItemName { get; set; }
public string SubItemName { get; set; }
}
My requirement is to get distinct sub item with their respective Item Names , Sub Item should be distinct but Item Name can be repeated as one Item can contain multiple Subitem
Distinct Does not work on multiple values so I tried
List<SubItemList> SI_List =
AnswerList.GroupBy(d => d.SubItemID)
.Select(x =>
new SubItemList
{
ItemName = x.Select(a => a.ItemName).First(),
SubItemName = x.Select(a => a.SubItemName).First()
}).Distinct().ToList();
This way I am getting what I want but I don't think its a preferable approach ,
Linq expression inside another Linq expression
How can I get it with a simple Linq expression ?
I am using ASP.Net Core 2.0
If the expectation is what you have asked in the question, then following shall be the query:
AnswerList.GroupBy(d => new { d.SubItemID, d.ItemName, d.SubItemName})
.Select(x => new SubItemList{
ItemName = x.Key.ItemName,
SubItemName =x.Key.SubItemName
}
).Distinct();
How it works
GroupBy unique combination of SubItemID, ItemName, SubItemName, which will form the grouping key
Now only Pick the ItemName, SubItemName to create SubItemList and call Distinct to remove duplicates even across SubItemID
For Distinct to work correctly for the class SubItemList either implement IEquatable<SubItemList> or supply the IEqualityComparer<SubItemList> to the Distinct
Try with
GroupBy(
p => new {p.ItemName, p.SubItemName}
).Select(g => new { g.Key.ItemName, g.Key.SubItemName });

Find object with in class using LINQ

I want to return the item that has the profile ID I send. So in order to do this I will need to loop through all of the Items -> WebProproperties -> profile. The Class structure is at the end of the question.
I would rather use LINQ than create a nested foreach. I have been trying to get this to work for more than an hour now. I am stuck.
My first idea was to simply use where. But that doesn't work because you need to have something on the other side that needs to equal.
this.Accounts.items.Where(a => a.webProperties.Where(b => b.profiles.Where(c => c.id == pSearchString)) ).FirstOrDefault();
My second idea was to try using Exists which I don't have much experience with:
Item test = from item in this.Accounts.items.Exists(a => a.webProperties.Exists(b => b.profiles.Exists(c => c.id == pSearchString))) select item;
This doesn't work either:
Could not find an implementation of query pattern for source type 'Bool'
public RootObject Accounts {get; set;}
public class RootObject
{
public string kind { get; set; }
public string username { get; set; }
public int totalResults { get; set; }
public int startIndex { get; set; }
public int itemsPerPage { get; set; }
public List<Item> items { get; set; }
}
public class Profile
{
public string kind { get; set; }
public string id { get; set; }
public string name { get; set; }
public string type { get; set; }
}
public class WebProperty
{
public string kind { get; set; }
public string id { get; set; }
public string name { get; set; }
public string internalWebPropertyId { get; set; }
public string level { get; set; }
public string websiteUrl { get; set; }
public List<Profile> profiles { get; set; }
}
public class Item
{
public string id { get; set; }
public string kind { get; set; }
public string name { get; set; }
public List<WebProperty> webProperties { get; set; }
}
You can use Any() to determine existence. Also, note that many of the extension methods have overloads which take a predicate, including FirstOrDefault():
this.Accounts.items.FirstOrDefault(a => a.webProperties
.Any(b => b.profiles
.Any(c => c.id == pSearchString)));
You are looking for the .Any() operation I think. This will return true/false for whether there are any items matching your query.
For example:
if (this.Accounts.Items.Any(i=>i.webProperties.Any(wp=>wp.profiles.Any(p=>p.id == MySearchId)));
EDIT: You have full answer (was posted while I was composing mine) and as pointed out in comments my answer isn't actually returning your found item, just letting you know whether there is one. You can rework the first .Any to be a .FirstOrDefault to get that match.
E.g.
var result = this.Accounts.Items.FirstOrDefault(i=>i.webProperties.Any(wp=>wp.profiles.Any(p=>p.id == MySearchId)))
You can use the below mentioned code.
var abc = rr.items.Where(p => p.webProperties.Any(c => c.profiles.Any(d => d.id == "1"))).FirstOrDefault();
Just for your reference, your class should look like:
public class RootObject
{
public string kind { get; set; }
public string username { get; set; }
public int totalResults { get; set; }
public int startIndex { get; set; }
public int itemsPerPage { get; set; }
private List<Item> _items=new List<Item>();
public List<Item> items
{
get { return _items; }
set { _items = value; }
}
}

Linq select nested rows

I have the following class:
public class PingtreeTier
{
public BuyerType BuyerType { get; set; }
public int ID { get; set; }
public int MaxRequests { get; set; }
public IEnumerable<PingtreeNode> Nodes { get; set; }
public int Seq { get; set; }
public int Timeout { get; set; }
public bool Weighted { get; set; }
}
As you can see PingtreeTier contains an IEnumerable<PingtreeNode> class. This PingtreeNode class has a property named Status. Using Linq, I need to select only the Tiers/Nodes where PingtreeNode Status = 'Active'.
Anyone help as I'm struggling with the syntax for this.
How about using .Any or .All here:
var results = tiers.Where(t => t.Nodes.Any(n => n.Status == "Active"));
This will select any PingtreeTiers that contain at least one PingTreeNode with Status equal to "Active".
If you wanted to select only PingtreeTiers whose PingTreeNodes are all active, you could use the .All extension method instead:
var results = tiers.Where(t => t.Nodes.All(n => n.Status == "Active"));

How to use selectmany in linq?

The following is my linq query
var meetingIndividualQuery = meetingsList.SelectMany(o => o.Attendies.Distinct().Where(x => x.CompanyId == company.CompanyId));
I have the following class
public class Meetings
{
public string IndustryCouncil { get; set; }
public string MeetingType { get; set; }
public string MeetingDescription { get; set; }
public string MeetingDate { get; set; }
public string MeetingHours { get; set; }
public string MeetingHourlyValue { get; set; }
public string MeetingTotal { get; set; }
public List<Individual> Attendies { get; set; }
}
With the above query I am getting the correct list of individaul but how I can I use the same query with the same condition to retrieve the list of Meetings. Can you please provide me any code
Following query will return list of meetings, which have at least one attendee with provided company id:
var query = meetingsList.Where(m => m.Attendies.Any(i => i.CompanyId == company.CompanyId));
You can also apply Distinct to Attendies before verifying Any

Categories

Resources