bExplosion
bExplosion

Reputation: 187

How to Join 2 Generic IEnumerators

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

Upvotes: 1

Views: 362

Answers (4)

Amy B
Amy B

Reputation: 110221

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);
}

Upvotes: 1

paracycle
paracycle

Reputation: 7850

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.

Upvotes: 6

John Fisher
John Fisher

Reputation: 22727

Which things are you merging?

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

Upvotes: 0

Joel Coehoorn
Joel Coehoorn

Reputation: 416149

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

Upvotes: 0

Related Questions