tags:

views:

86

answers:

4

Hey all,

I'm wondering if its possible to join together IEnumerable's.

Basically I have a bunch of users and need to get their content from the database so I can search and page through it.

I'm using LINQ to SQL, my code at the moment it:

        public IEnumerable<content> allcontent;

        //Get users friends
        IEnumerable<relationship> friends = from f in db.relationships
                                            where f.userId == int.Parse(userId)
                                            select f;

        IEnumerable<relationship> freindData = friends.ToList();

        foreach (relationship r in freindData)
        {
          IEnumerable<content> content = from c in db.contents
                                          where c.userId == r.userId
                                          orderby c.contentDate descending
                                          select c;

         // This is where I need to merge everything together
        }

I hope that make some sense!

Matt

A: 

If you're doing an INNER join, look at the .Intersect() extension method.

Joel Coehoorn
A: 

Which things are you merging?

There are two main options you could use: .SelectMany(...) or .Concat(...)

John Fisher
Currently its getting user1's content then user 2 and so on. I'm wanting to merge all that together. So I end up with user 1 + 2 + 3 etc.
bExplosion
Ah. The placement of your "this is where..." comment threw me off. (It's inside the for loop.)
John Fisher
+6  A: 

If I understand correctly what you are trying to do, why don't you try doing:

var result = from r in db.relationships
             from c in db.contents
             where r.userId == int.Parse(userId)
             where c.userId == r.UserId
             orderby c.contentDate descending
             select new {
               Relationship = r,
               Content = c
             }

This will give you an IEnumerable<T> where T is an anonymous type that has fields Relationship and Content.

paracycle
+1  A: 

If you know your users will have less than 2100 friends, you could send the keys from the data you already loaded back into the database easily:

List<int> friendIds = friendData
  .Select(r => r.UserId)
  .Distinct()
  .ToList();

List<content> result = db.contents
  .Where(c => friendIds.Contains(c.userId))
  .ToList();

What happens here is that Linq translates each Id into a parameter and then builds an IN clause to do the filtering. 2100 is the maximum number of parameters that SQL server will accept... if you have more than 2100 friends, you'll have to break the ID list up and combine (Concat) the result lists.


Or, if you want a more literal answer to your question - Concat is a method that combines 2 IEnumerables together by creating a new IEnumerable which returns the items from the first and then the items from the second.

IEnumerable<content> results = Enumerable.Empty<content>();
foreach (relationship r in friendData)
{
    IEnumerable<content> content = GetData(r);
    results = results.Concat(content);
}
David B
Thanks a lot mate! I ended up changing a few things and writing a better LINQ statement, but this is going to come in super handy!
bExplosion