2014-02-07 56 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; 
} 

对不起,没有测试过这一点,但它应该工作。