6

I have a collection of ID numbers that I wish to return some object for, I'm doing it by using a linq statement with a where that's using a contains statement:

var recentCats = (from i in EntityCache.Default.GetAll<Categories>()
                          where WebProfile.Current.RecentlyCreatedCategories.Contains(i.Id)
                          && BoundCategory.ParentItemClass.Id.Equals(i.ParentItemClass.Id)
                          select new CategoryInfo()
                          {
                              Category = i,
                              ClassId = i.ParentItemClass.Id,
                              ClassImage = NamedResourceManager.GetResourceBinary(i.ParentItemClass.NameResourceId)
                          });

This works perfectly fine, except that I want to keep the order of items in the returned collection the same as they were in the list that goes in. So for example if I had a list of IDs: 14, 603, 388, I want the objects that come back to be in the same order, not the order that they're returned by the cache. Is there any way in entity framework to do this, or any way to do it that doesn't involve me writing a foreach loop?

Thanks

Gent
  • 2,675
  • 1
  • 24
  • 34
Mathew Collins
  • 376
  • 3
  • 14
  • Sorry don't have time for a full answer, but I can give you a hint. It involves joining your ID list onto the category list instead of using the `where ... contains` – Ray Dec 29 '11 at 15:54
  • I think the problem here is, that there is no order for SQL, unless you order explicitly. SQL can return in any order, so there is no default order to keep. – Euphoric Dec 29 '11 at 18:52

2 Answers2

3

The Where Linq extension as with most extensions maintains the original order of the list.

Do LINQ's Enumerable Methods Maintain Relative Order of Elements?

As long as you do not explicitly reorder or use an operator that naturally would reorder the original list's order should be maintained. Obviously reordering the list for a where statement would be unneeded overhead.


The reason the information above does not apply to this question is in the comments bellow. I would suggest changing the output of the select to be a key/value pair, where the key is the index of the Id in your list, and the value is your new object, then orderBy the key on the resulting set, and select the value.

Community
  • 1
  • 1
Gent
  • 2,675
  • 1
  • 24
  • 34
  • 1
    That's LINQ to Objects. He's using EF, which will return the order from SQL Server. – SLaks Dec 29 '11 at 17:19
  • @SLaks thank you for the information, I have edited my answer with a possible solution. – Gent Dec 29 '11 at 18:35
  • Thanks for the explanation and the link. It's not quite what I'm looking for though, as I don't think I was specific enough in my question. At the moment my results are coming back in the order they're in in the cache, since that's the query I'm running - I wanted them to be in the order of the list I'm checking instead. I can do that by using a join as mentioned by Ray above instead of the contains clause. – Mathew Collins Dec 30 '11 at 09:24
2

For anyone interested, I was able to get them to come out in the same order as the list by joining them, as mentioned by Ray in the comments above.

var recentCats = (from i in WebProfile.Current.RecentlyCreatedCategories
                              join b in allCats
                                on i equals b.Id
                              where BoundCategory.ParentItemClass.Id.Equals(b.ParentItemClass.Id)
                              select ...

Thanks again for all your help & answers.

Mathew Collins
  • 376
  • 3
  • 14