Linq - Retrieve first list after SelectMany - linq

I've an object list where each object contains an internal object list and what I would fetching is the father list (left list), however I'm forced to use SelectMany function..Is it possibile?
Naive Example:
var query = objList.SelectMany(p => p.InternalList)
.Where(internalObj => internalObj.SomeProprerty == true)
.SELECT(objList);
Is there any way to accomplish this?

Assuming you don't actually want objList, but instead the element of objList which we're looking at at the time, I think you just want:
var query = objList.SelectMany(p => p.InternalList, (o, p) => new { o, p })
.Where(pair => pair.p.SomeProperty)
.Select(pair => pair.o);
If that's not what you're after, it would really help if you'd give a concrete example.
EDIT: If you only want any example from objList where any element of the internal list has a SomeProperty value of true, you can do that more easily like this:
var value = objList.FirstOrDefault(o => o.InternalList.Any(p => p.SomeProperty));
if (value != null)
{
...
}

Related

LINQ query to return first item in an ordered grouping

Grouping is an area of LINQ that I haven't quite managed to get my head around yet. I have the following code:
var subTrips = tbTripData
.Where(t => selectedVehicleIds.Contains(t.VehicleID))
.Join(tbSubTripData,
t => t.TripID,
s => s.TripID,
(t, s) => new { t = t, s = s })
.Select(r =>
new SubTrip
{
VehicleID = r.t.VehicleID,
TripID = r.t.TripID,
Sequence = r.s.Sequence,
TripDistance = r.s.TripDistance,
Odometer = r.s.Odometer
})
.ToList();
I'm trying to figure out a LINQ query that will look at subTrips and for each VehicleID, find the first Odometer, i.e. the Odometer corresponding to the lowest TripID and Sequence values.
I've been poking at it for an hour but just can't figure it out. Can anyone offer some advice before I give up and write procedural code to do it?
UPDATE: To clarify, Sequence is the sequential number of each subtrip within a trip. So what I'm looking for is the Odometer from the first subtrip for each vehicle when the subtrips within each grouped VehicleID are ordered by TripID then by Sequence.
I'm not 100% what you're looking for. But this might get you started in the right direction.
var groupedList = (from s in subTrips
group s by s.VehicleID
into grp
select new
{
VehicleID = grp.Key,
Odometer = grp.OrderBy(ex => ex.TripID).Select(ex => ex.Odometer).First(),
TripID = grp.Min(ex => ex.TripID)
}
).ToList();
This will return the VehicleID, the Odometer corresponding to the lowest TripID, and the lowest TripID.

How to order a LinQ result set created by a list of ID and order it use existing order of the list

My code is something like this:
List<int> IDs = new List<int> {9,7,38, 23}
IQueryable<Post> pp = myDataEntity.Posts.Where(p=>IDs.Contains(p.ID));
How can I explain that I want to sort pp by the order of ID in the IDs? Thank you.
You can order by List.IndexOf:
IQueryable<Post> orderedPosts myDataEntity.Posts
.Select(p => new { Post=p, Index=IDs.IndexOf(p.ID) })
.Where(x => x.Index >= 0)
.OrderBy(x => x.Index)
.Select(x => x.Post);
Assuming you want to keep the order of ID you have in IDs and not actually the ordered verison of it, this is how you can do it:
var pp = IDs.Select(x=> myDataEntity.Posts.Where(p=>p.ID == x))
.SelectMany(x=>x);
Using IDs as your external collection, you get to keep the ordering of the elements in it.
use OrderByDescending
IQueryable<Post> pp = myDataEntity.Posts.Where(p=>IDs.Contains(p.ID))
.OrderByDescending(p => p.ID)

LINQ read Select values

I have a LINQ query where I want to select and read the p.Api value.
var api = DataAccessNew.Instance.dcServers.Where(p => p.Ip == IpAddress).Select(p => p.Api);
How do I read the p.Api value?
I have tried api.ToString() but I get SQL instead of actual column value.
You are getting an IEnumerable<> back (and your ToString call is showing you the value of that expression).
If you are expecting a single value, do this:
var api = DataAccessNew.Instance.dcServers
.Where(p => p.Ip == IpAddress)
.Select(p => p.Api)
.Single();
You might be interested to read about the other methods like Single(): SingleOrDefault, First, FirstOrDefault. Which one you used depends on whether you are expecting a single or multiple values returned (Single vs. First) and what you want to happen if there are no values (the *Default methods will return the type default instead of throwing an exception).
Or if you want to look at all the returned values:
var api = DataAccessNew.Instance.dcServers
.Where(p => p.Ip == IpAddress)
.Select(p => p.Api);
foreach (var apiValue in api)
{
// apiValue will have the value you're looking for.
}
Try this snippet of code:
string apiValue = api.FirstOrDefault().ToString();
your syntex seems ok..
By the way try this
string api =DataAccessNew.Instance.dcServers.Where(p => p.Ip == IpAddress).Select(p => p.Api).FirstOrDefault();
if p.Ip is a unique key in your table you could try to add .FirstOrDefault() after your Linq query.
public string getselectedvalue(ListBox l)
{
string vtext="",vval="";
var selectedQueryText = l.Items.Cast<ListItem>().Where(item => item.Selected);
var selectedQueryVal = l.Items.Cast<ListItem>().Where(item => item.Selected).Select(item => item.Value);
vtext= String.Join("','", selectedQueryText ).TrimEnd();
vval= String.Join("','", selectedQueryVal ).TrimEnd();
return v;
}

LINQ Group By into a Dictionary Object

I am trying to use LINQ to create a Dictionary<string, List<CustomObject>> from a List<CustomObject>. I can get this to work using "var", but I don't want to use anonymous types. Here is what I have
var x = (from CustomObject o in ListOfCustomObjects
group o by o.PropertyName into t
select t.ToList());
I have also tried using Cast<>() from the LINQ library once I have x, but I get compile problems to the effect of it being an invalid cast.
Dictionary<string, List<CustomObject>> myDictionary = ListOfCustomObjects
.GroupBy(o => o.PropertyName)
.ToDictionary(g => g.Key, g => g.ToList());
I cannot comment on #Michael Blackburn, but I guess you got the downvote because the GroupBy is not necessary in this case.
Use it like:
var lookupOfCustomObjects = listOfCustomObjects.ToLookup(o=>o.PropertyName);
var listWithAllCustomObjectsWithPropertyName = lookupOfCustomObjects[propertyName]
Additionally, I've seen this perform way better than when using GroupBy().ToDictionary().
For #atari2600, this is what the answer would look like using ToLookup in lambda syntax:
var x = listOfCustomObjects
.GroupBy(o => o.PropertyName)
.ToLookup(customObject => customObject);
Basically, it takes the IGrouping and materializes it for you into a dictionary of lists, with the values of PropertyName as the key.
This might help you if you to Get a Count of words. if you want a key and a list of items just modify the code to have the value be group.ToList()
var s1 = "the best italian resturant enjoy the best pasta";
var D1Count = s1.ToLower().Split(' ').GroupBy(e => e).Select(group => new { key = group.Key, value = group.Count() }).ToDictionary(e => e.key, z => z.value);
//show the results
Console.WriteLine(D1Count["the"]);
foreach (var item in D1Count)
{
Console.WriteLine(item.Key +" "+ item.Value);
}
The following worked for me.
var temp = ctx.Set<DbTable>()
.GroupBy(g => new { g.id })
.ToDictionary(d => d.Key.id);

How to query a nested list using a lambda expression

In my repository implementation I can run the following query using a lambda expression:
public IList<User> GetUsersFromCountry(string)
{
return _UserRepository.Where(x => x.Country == "Sweden").ToList();
}
So far so good, simple stuff. However, I'm having difficulties to write a lambda expression against a nested -> nested list. Given the following example (sorry couldn't think of a better one):
The following query works absolutely fine and returns all clubs, which have members over the age of 45
public IList<Clubs> GetGoldMembers()
{
var clubs = from c in ClubRepository
from m in c.Memberships
where m.User.Age > 45
select c;
return clubs;
}
At the moment, this is where my knowledge of lambda expression ends.
How could I write the above query against the ClubRepository, using a lambda expression, similar to the example above?
This might work (untested)...
var clubs = ClubRepository.Where(c=>c.MemberShips.Any(m=>m.User.Age > 45));
Here's one way to do it:
var clubs = clubRepository
.SelectMany(c => c.Memberships, (c, m) => new { c, m })
.Where(x => x.m.User.Age > 45)
.Select(x => x.c);
A more generic way
List<T> list= new List<T>();
list= object1.NestedList1.SelectMany(x => x.NestedList2).ToList();
Where NestedList2 matches the data type of "list"

Resources