Shipu
Shipu

Reputation: 563

The query results cannot be enumerated more than once

Consider the following methods. I am getting exception as asked , while repeater binding.

Bindrepeater:

private void BindRepeater()
{
    var idx = ListingPager.CurrentIndex;
    int itemCount;
    var keyword = Keywords.Text.Trim();
    var location = Area.Text.Trim();
    var list = _listing.GetBusinessListings(location, keyword, idx, out itemCount);
    ListingPager.ItemCount = itemCount;
    BusinessListingsRepeater.DataSource = list.ToList(); // exception here
    BusinessListingsRepeater.DataBind();
}

GetBusinessListings:

public IEnumerable<Listing> GetBusinessListings(string location, string keyword, int index, out int itemcount)
{
    var skip = GetItemsToSkip(index);
    var result = CompiledQueries.GetActiveListings(Context);
    if (!string.IsNullOrEmpty(location))
    {
      result= result.Where(c => c.Address.Contains(location));
    }
    if (!string.IsNullOrEmpty(keyword))
    {
        result = result.Where(c => c.RelatedKeywords.Contains(keyword) || c.Description.Contains(keyword));
    }
    var list = result;

    itemcount = list.Count();
    return result.Skip(skip).Take(10);

}

GetActiveListings :

/// <summary>
///   Returns user specific listing
/// </summary>
public static readonly Func<DataContext, IQueryable<Listing>> GetActiveListings =
    CompiledQuery.Compile((DataContext db)
                          => from l in db.GetTable<Listing>()
                             where l.IsActive 
                             select l);

Upvotes: 2

Views: 2398

Answers (2)

Mathias Becher
Mathias Becher

Reputation: 703

When you assign itemcount you are executing the query the first time. Why do you need this? My suggestion would be not to retrieve the item count there and just

return result.Skip(skip).Take(10).ToList();

Basically you can't have both, fetch only the results you need and retrieve the total count in one query. You could use two seperate querys though.

Upvotes: 6

Daniel A. White
Daniel A. White

Reputation: 190945

You may want to persist your results as a collection, not an IQueryable.

var list = result.ToArray();

itemcount = list.Length;
return list.Skip(skip).Take(10);

The above code may not be correct for paging. You likely will have to run the query twice.

Upvotes: 2

Related Questions