0

I have a loop inside my program, which loops through thousands of object to find the right one with particular id. is there any better and faster way than this

int id;
SPList list = SPContext.Current.Web.Lists.TryGetList("DataLibrary");
IEnumerable<SPListItem> _dataitems = list.Items.OfType<SPListItem>();

foreach (SPListItem item in _dataextantitems)
{
    if (item.ID == id)
    {
        title= item.Title;
    }
}
Dimitar Dimitrov
  • 14,868
  • 8
  • 51
  • 79
user388969
  • 337
  • 1
  • 9
  • 30
  • I think you have missed some code. – Ben Robinson Dec 11 '14 at 16:37
  • i have shown just the part of code for the loop. what happens inside the loop is not important i guess. – user388969 Dec 11 '14 at 16:38
  • Perhaps you are looking for finding a single item from your collection, use `var item = _dataitems.FirstOrDefault(r=> r.ID == id);`. See: http://stackoverflow.com/questions/12477422/how-to-use-returned-linq-variable/12477454#12477454 – Habib Dec 11 '14 at 16:40
  • 1
    @DimitarDimitrov Locals cannot be used until they are assigned; the code won't *compile* unless he assigns a value to it. Presumably the code to generate the ID simply isn't relevant to us. – Servy Dec 11 '14 at 17:01
  • @Servy :P Yep, you're right of course :) My bad. – Dimitar Dimitrov Dec 11 '14 at 17:02

2 Answers2

4

Use the GetItemById of SPList.

var title = SPContext.Current.Web.Lists["DataLibrary"].GetItemById(id).Title;

If your list has a lot of columns, and you want to avoid pulling them all down, you can pull down just the Title column instead:

var title = SPContext.Current.Web.Lists["DataLibrary"]
    .GetItemByIdSelectedFields(id, "Title").Title;

Now if you really want to use LINQ here you could use LINQ to Sharepoint, but it's not actually going to simplify the code a ton. After using SPMetal.exe to generate a file based on your lists, you'd be able to write:

using(var context = new YourContextNameHere(SPContext.Current.Site.Url))
{
    var title = context.DataLibrary
        .Where(item => item.ID == id)
        .Select(item => item.Title)//to avoid pulling down other columns
        .First();
}
Servy
  • 202,030
  • 26
  • 332
  • 449
  • is it faster than the foreach loop or the code i have above, what if the id is not present in the list. this will throw an exception?? – user388969 Dec 11 '14 at 18:07
  • 1
    It will be *dramatically* faster. – Servy Dec 11 '14 at 18:09
  • @user388969 If you need your code to not throw if the ID is not present then you'll want to write a CAML query comparing the ID field to the ID that you have, and execute that query against the list, which is what `GetItemById` is going to do under the hood. – Servy Dec 11 '14 at 18:11
0

Make sure your list is sorted. Then you can use the BinarySearch method of the list or write your own implementation. If not you can shorten your code using linq.

var itemToLookup = list.Items.OfType<SPListItem>().FirstOrDefault(x => x.ID == id);
if (itemToLookup != null)
{
      //...
}
Community
  • 1
  • 1
Jessica
  • 23
  • 5
  • 3
    So you're suggesting he pull down the entire table's worth of data, from the database, into memory, sort the whole thing, and then search through it to find the ID, instead of just querying the database for the item with that ID? – Servy Dec 11 '14 at 16:56
  • No - only if there is no other option... But since it's sharepoint, and there is a rest interface that allows you to qry directly on ID, there is no need for it. As shown in your answer. – Jessica Dec 11 '14 at 17:32
  • I am finding the list item with a particular id then i have 35 more columns. I need to get the data of all the columns and print in output. I thought for each loop will loop through all the items, which will have the n loops if thee are n items. so was looking for a faster way in terms of performance – user388969 Dec 11 '14 at 17:59