我正在尝试找出通过各种函数呼叫连续迭代的好方法,最后一次循环。
本质上,我在数据库中有很多广告,我想在dbset.ads
上获取(计数)这是一个示例
ID Text Other Columns...
1 Ad1 ...
2 Ad2 ...
3 Ad3 ...
4 Ad4 ...
5 Ad5 ...
6 Ad6 ...
我认为,我确定我需要2个广告才能显示为用户1.我想返回AD 1-2。用户2然后请求3个广告。我希望它返回3-5。用户3需要2个广告,并且该功能应返回AD 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] skipwher [ad](system.linq.iqueryable'1 [domain.entities.ad],system.linq。expressions.expression'1 [system.func`2 [domain.entities.ad,system.boolean]])'方法,此方法无法转换为存储表达式。
我最初已将整个DBSET加载到队列中,并进行了加入/Dequeue,但是当对数据库进行更改时,这不会更新。我根据ID和名称,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;
}
SkipWhile
不支持EF;它不能翻译成SQL代码。EF基本上是在集合而不是序列上工作的(我希望句子有意义)。
解决方法就是简单地使用Where
,例如:
IEnumerable<Ad> Ads = db.Ads.OrderBy(x=>x.Id).Where(x=>x.Id >= NextAd.Id);
也许您可以将其简化为类似的东西:
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;
}
对不起,还没有测试过,但是应该起作用。