2014-02-07 99 views
0

我想找出什麼是一個很好的方式來通過各種函數調用不斷循環dbset,循環一次在最後。通過dbset迭代獲得下n行

基本上我有一堆數據庫廣告,我想GETNEXT(計數)在dbset.Ads

下面是一個例子

ID Text Other Columns... 
1 Ad1 ... 
2 Ad2 ... 
3 Ad3 ... 
4 Ad4 ... 
5 Ad5 ... 
6 Ad6 ... 

比方說,在我看來, ,我確定我需要2個廣告才能顯示給用戶1.我想返回廣告1-2。用戶2然後請求3個廣告。我希望它返回3-5。用戶3需要2個廣告,並且該功能應該返回廣告6和1,循環回到開始。

這裏是我的代碼,我一直在使用(它在class AdsManager):

Ad NextAd = db.Ads.First(); 
public IEnumerable<Ad> getAds(count) 
{ 
    var output = new List<Ad>(); 
    IEnumerable<Ad> Ads = db.Ads.OrderBy(x=>x.Id).SkipWhile(x=>x.Id != NextAd.Id); 
    output.AddRange(Ads); 

    //If we're at the end, handle that case 
    if(output.Count != count) 
    { 
     NextAd = db.Ads.First(); 
     output.AddRange(getAds(count - output.Count)); 
    } 
    NextAd = output[count-1]; 

    return output; 
} 

的問題是,函數調用IEnumerable<Ad> Ads = db.Ads.OrderBy(x=>x.Id).SkipWhile(x=>x.Id != NextAd.Id);略知AddRange(Ads)的錯誤:

LINQ到實體不識別方法'System.Linq.IQueryable'1 [Domain.Entities.Ad] SkipWhile [Ad](System.Linq.IQueryable'1 [Domain.Entities.Ad],System.Linq.Expressions.Expression'1 [System。 Func`2 [Domain.Entities.Ad,System.Boolean]])方法,並且此方法不能轉換爲存儲表達式。

我原來已經把整個dbset加載到隊列中,並且已經入隊/出隊,但是當對數據庫進行改變時不會更新。我想到了這個算法的基礎上Get the next and previous sql row by Id and Name, EF?

我應該對數據庫做什麼調用來得到我想要的?

更新:這裏的工作代碼:

public IEnumerable<Ad> getAds(int count) 
    { 
     List<Ad> output = new List<Ad>(); 

     output.AddRange(db.Ads.OrderBy(x => x.Id).Where(x => x.Id >= NextAd.Id).Take(count + 1)); 

     if(output.Count != count+1) 
     { 
      NextAd = db.Ads.First(); 
      output.AddRange(db.Ads.OrderBy(x => x.Id).Where(x => x.Id >= NextAd.Id).Take(count - output.Count+1)); 
     } 

     NextAd = output[count]; 
     output.RemoveAt(count); 

     return output; 
    } 

回答

0

SkipWhile在EF不支持;它不能被翻譯成SQL代碼。英孚基本上是在集合上工作而不是序列(我希望這句話很有意義)。

一種解決方法是簡單地使用Where,如:

IEnumerable<Ad> Ads = db.Ads.OrderBy(x=>x.Id).Where(x=>x.Id >= NextAd.Id); 
+0

我可以欣賞簡單。那麼爲了加入'count',我只是像'if'語句中那樣使用'Take()' – CrazyTegger

0

也許你可以簡化這個弄成這個樣子:

Ad NextAd = db.Ads.First(); 

public IQueryable<Ad> getAds(count) 
{ 
    var firstTake = db.Ads 
     .OrderBy(x => x.Id) 
     .Where(x => x.Id >= NextAd.Id); 

    var secondTake = db.Ads 
     .OrderBy(x => x.Id) 
     .Take(count - result.Count()); 

    var result = firstTake.Concat(secondTake); 

    NextAd = result.LastOrDefault() 

    return result; 
} 

對不起,沒有測試過這一點,但它應該工作。