tags:

views:

392

answers:

2

I have a collection of objects called Gigs.

Each Gig has an Acts collection.

Using Linq I want to query my collection of gigs to get all gigs where with an act that has an id of 7 for example.

act.id = 7;

So I started writting...

return from gig in qry
       where gig.Acts //not sure how to do this bit
       select gig;

But I'm not sure how you set conditions on the child collection called acts.

Any ideas?

+5  A: 
var x = gigs.Where(g=>g.Acts.Select(a=>a.ID).Contains(7));

these two queries also return the same:

var x = gigs.Where(g=>g.Acts.Count(a=>a.ID == 7) > 0);

var x = gigs.Where(g=>g.Acts.FirstOrDefault(a=>a.ID == 7) != null);
Mike_G
Linq is really, weird since there are a couple ways to write the same query.
Mike_G
So the full request is....var x = gigs.Where(g=>g.Acts.Select(a=>a.Artist.ID).Contains(7));If Artists is null (which is perfectly valid) I get an exception...'Shared.DO.Artist Artist' of 'Shared.DO.Act' not legal on type 'System.Collections.Generic.List`1[Shared.DO.Act]Hmmm thoughts?
ListenToRick
Just modify it too look at the artist first, before checking the ID:var x = gigs.Where(g=>g.Acts.Select(a=>a.Artist).Select(b=>b.ID).Contains(7));or
Mike_G
var x = gigs.Where(g=>g.Acts.Count(a=>a.Artist!=null
Mike_G
+4  A: 

Essentially the same as Mike_G, only more verbose syntax and using equality.

var myCollection = from gig in qry
                   where gig.Acts.Any(act => act.ID == 7)
                   select gig;

Just an edit to bring comments to the answer:

Actually query is for an ID on a member (Artist) on the Act object that can be null.

new Query:

var myCollection = from gig in qry
                   where gig.Acts.Any(act => (null != act.Artist) && (act.Artist.ID == 7))
                   select gig;
Quintin Robinson
Yours is actually a little off since Acts is a collections itself, that does not have a property of ID.
Mike_G
yes I realized that after I wrote it.. Derp, was just going to edit.
Quintin Robinson
I completely forgot about Any! I wonder which out of all the queries listed, which is the fastest.
Mike_G
I get this error when I try this: Member access 'Shared.DO.Artist Artist' of 'Shared.DO.Act' not legal on type 'System.Collections.Generic.List`1[Shared.DO.Act]Acts is a List<Act>Any ideas?
ListenToRick
Note... my actual request was:from gig in qry where gig.Acts.Any(act => act.Artist.ID == 7) select gig;Artist can be null!How do I account for this??
ListenToRick
Can you edit your post with a simple definition of the Gig and Act objects, it sounds like a member (Artist) on the Act object is inaccessible, but I can't really tell.
Quintin Robinson
Quintin Robinson
I edited my question a moment ago to bring the actual answer into context. It should work, please let me know.
Quintin Robinson
So the full query is now: return from gig in qry where gig.Acts.Any(act => (null != act.Artist) I still get the same exception when I call allItems.Count() on the data..
ListenToRick
is allitems the variable you are setting to the return of your method call? Try doing alltimes.ToList().Count and see if it is zero. It sounds odd that it would be the exact same exception unless the getter for Artist does something that can throw a nullreference
Quintin Robinson
Calling IList<Gig> list = gigs.ToList(); (where gigs is the result) causes the same exception... IList<Gig> list = gigs.ToList();Member access 'Shared.DO.Artist Artist' of 'Shared.DO.Act' not legal on type 'System.Collections.Generic.List`1[Shared.DO.Act]
ListenToRick
If I simplify the query to:return from gig in qry where gig.Acts.Any(act => act.ID == actId)orderby gig.StartDate select gig;I get the exception:Member access 'System.Guid ID' of 'Shared.DO.BaseDO' not legal on type 'System.Collections.Generic.List`1[Shared.DO.Act]
ListenToRick
Note: BaseDO is just a simple object with a Guid ID property
ListenToRick
is the artist field setup as a reference to act through a datacontext/emf or are these custom POCOs? I am not familiar with that particular exception and am having a problem figuring out exactly what would cause this.
Quintin Robinson
I assume BaseDO is a base class, what is the modifier for the class and the ID property.. public?
Quintin Robinson
Yep - its all public... I wonder if it could be to do withe intial LinqToSql request? Basically I have a linqToSql request which gets returned as an IQueryable<Gig>. I'm then filtering further using the linq statement that you've already seen. I'll post the linqToSql statement..
ListenToRick
return from g in DBContext.Gigs let acts = GetActs(g.ID) select new Shared.DO.Gig { ID = g.ID, Name = g.Name, Acts = new List<Shared.DO.Act>(acts), };
ListenToRick
The GetActs just returns a collection of IQueryable<Shared.DO.Act>
ListenToRick
That might be the problem it must be breaking the entityreference when for the Artist object on Acts when assigning acts to a new list on a new object of Gig. well this may be suboptimal but try Acts = acts.ToList() instead of passing the queryable to the ctor of list.
Quintin Robinson
Tried that - no such luck. The same probelm still arises...
ListenToRick
I removed from the LinqToSql query the request for the acts data. So now every Gig object will have an unpopulated Acts collection. When I query the gigs collection the problem still occurs! So it seems its something to do with my object structure?? I post the object defs below
ListenToRick
public class Gig : BaseDO { public IList<Act> Acts { get; set; } #endregion }
ListenToRick
public class BaseDO: IDO { #region IDO Members public Guid ID { get; set; }}}
ListenToRick
public class Act : BaseDO { public Guid GigId { get; set; } public string Name { get; set; } public Artist Artist { get; set; } }
ListenToRick
If I build the gigs collection manually - i.e. in code and not from the database, the query works fine. However, if grab it from the LinqToSQL the exception occurs, even if I'm not populating the acts collection in the LInqToSQl.
ListenToRick
I've reasked this question with a bit more detail related to this bug here: http://stackoverflow.com/questions/524062/linqtosql-and-the-member-access-not-legal-on-type-exception
ListenToRick