Struggling with .ToList() returing an EntitySet<...>, not an IList<..> - linq

I'm trying to retrieve a list of Id's from a collection that is a few levels deep in an object heirachy. When i try to do a ToList(), I keep getting an EntityList<> retrieved instead .. which means it's not allowing me to retrieve an instance's BarId property because the EntitySet is a Enumerable, not a single instance object.
Foo.Child1 (1 to 1)
Child1.Children2 (0 to many of type Bar)
Bar.BarId int;
IList<Foo> fooList = (from blah blah blah).ToList();
var children2List = (from x in fooList
select x.Child1.Children2).ToList();
It keeps returning children2List as an EntitySet<Bar>, not an IList<Bar>. As such, i'm struggling to retrieve the list of BarId's from children2List.
please help!

Your can use:
var children2List = fooList.SelectMany( x => x.Child1.Children2 ).ToList();
This will allow you to do something like:
children2List.ForEach( b => b.BarId.Print() );

In your query, you turn the whole result into a list, not the individual Children2 sets.
Try
var children2List = (from x in fooList
select x.Child1.Children2.ToList()).ToList();
This will turn each Children2 into a List.

EntitySet<T> implements IList<T>, so you already are returning IList<Bar>.

Related

Get All Entities From EntityCollection Where Values Matches X

I would like to get all matched Entities from an EntityCollection by a value, but my current statement only allow return of Entity, and not EntityCollection.
//only allow return 1 entity
var matchedRecords = allRecords.Entities.Where
(x => x.GetAttributeValue<EntityReference>
("ccc_batchId").Id == batchId);
May I know how can I tweak the above query?
EntityCollection is just a construct to store more than one Entity.
I know it's not ideal but you can always convert the allRecords.Entities inside a List of Entity and do your LINQ query against it.
Your code is probably returning an IEnumerable of Entity and not a single Entity (for example in the end of your query you can put a .ToList() to get a List of Entity.
Building on what Guido said, it is also possible to create a new EntityCollection with the results:
var matchedRecords = allRecords.Entities.Where(x => x.GetAttributeValue<EntityReference>("ccc_batchId").Id == batchId).ToList();
var matchedCollection = new EntityCollection(matchedRecords);

retrieve all areas where id's don't exist in supplied list

I'm sure I must be missing something really simple here..
OK I have a list of AreaIds. I want to compare that list to the MapArea Table and return any IDs that exist in the table but NOT in the supplied list.
This is my list of supplied areas that I want to check:
var currentAreas = (from c in _entities.mapAreaLink
where c.listingId == id
select new
{
c.MapArea.areaId
}
).ToList();
This is the getting the exhaustive list of mapAreas..
var availableAreas = (from m in _entities.MapAreas
select new
{
m.areaId
}
).ToList();
This compares the two lists and gets items that exist in the maparea table but not in the maparealink (constrained by an id of the item I am looking at).
var unusedAreas = availableAreas.Except(currentAreas).ToList();
I seem to get the list back ok, but what I need to do is now return a list of maparea objects based on the results of the Except.tolist above.
I thought I could do this:
var mapareas = (from e in _entities.MapAreas
where unusedAreas.Contains(e.areaId)
select e).ToList();
I am getting an ambiguous invocation on the where & "Cannot resolve method Contains(int)" on the e.areaId.
Ive tried using:
var unusedAreas = availableAreas.Except(currentAreas).ToArray();
No Joy.. Can anyone help me out here - I am guessing I must be missing a fundamental basic here.
many thanks
You create anonymous types with just one int property. That's not necessary and it causes the later problem. If you create lists of int you'll be OK:
var currentAreas = (from c in _entities.mapAreaLink
where c.listingId == id
select c.MapArea.areaId).ToList();
var availableAreas = (from m in _entities.MapAreas
select m.areaId).ToList();

Linq with DynamicObject

I have List where MyType : DynamicObject. The reason for MyType inheriting from DynamicObject, is that I need a type that can contain unknown number of properties.
It all works fine until I need to filter List. Is there a way I can do a linq that will do something like this:
return all items where any of the properties is empty string or white space?
(from the comment) can I do above linq query with List?
Yes, here is how you can do it with ExpandoObject:
var list = new List<ExpandoObject>();
dynamic e1 = new ExpandoObject();
e1.a = null;
e1.b = "";
dynamic e2 = new ExpandoObject();
e2.x = "xxx";
e2.y = 123;
list.Add(e1);
list.Add(e2);
var res = list.Where(
item => item.Any(p => p.Value == null || (p.Value is string && string.IsNullOrEmpty((string)p.Value)))
);
The ExpandoObject presents an interface that lets you enumerate its property-value pairs as if they were in a dictionary, making the process of checking them a lot simpler.
Well as long as each object's properties are not unknown internally to themselves you could do it.
There isn't a great generic way to test all the properties of a dynamic object, if you don't have control over the DynamicObject you hope the implementer implemented GetDynamicMemberNames() and you can use the nuget package ImpromptuInterface's methods for getting the property names and dynamically invoking those names.
return allItems.Where(x=> Impromptu.GetMemberNames(x, dynamicOnly:true)
.Any(y=>String.IsNullOrWhiteSpace(Impromptu.InvokeGet(x,y));
Otherwise, since it's your own type MyType you can add your own method that can see internal accounting for those member values.
return allItems.Where(x => x.MyValues.Any(y=>String.IsNullOrWhitespace(x));

LINQ / EF - Only return items based on a list of ID's

I have a list of type int, which contains ID's. For example it may contain 1,2,5,8,16 or 2,3,6,9,10,12 etc..
I then want to return all of my "Enquiries" based on the ID's stored in my list (called vehicles) and return them as a list, something like:
var enquiries = context.Enquiries.Where(x => x.EnquiryID == vehicles.Any()).ToList();
But obviously this doesn't work, is there something similar I can do?
You likely want to use Contains. Contains (in Linq2SQL or EF) will be transformed into a WHERE/IN clause.
enquiries = context.Enquiries
.Where( x => vehicles.Contains( x.EnquiryID ) )
.ToList();

LINQ where query on collection of different derived classes

I have a collection of different objects that derive from the same parent.
How can I extract objects of a particular type from a collection containing mixed types
e.g.
public class A {}
public class B : A {}
public class C : A {}
The collection will contain objects of type B and C
I'm halfway there just need help filling in the '[]' bit
var x = from xTypes in xCollection where '[type of object is type B]' select xTypes;
Thanks.
You should use the OfType<T> extension method rather than LINQ query syntax for this:
var x = xCollection.OfType<B>();
This will give you back an IEnumerable<B>. If you do want to use the LINQ query syntax, you'd have to do this:
var x = from obj in xCollection where obj is B select (B)obj;
var x = from xTypes in xCollection
where xTypes is B
select xTypes;
or if you want exactly this type and not any derived types:
var x = from xTypes in xCollection
where xTypes.GetType() == typeof(B)
select xTypes;

Resources