我试图找出在各种函数调用中不断迭代dbset的好方法,最后循环一次。
基本上我在数据库中有很多广告,我想在dbset.Ads上获取下一个(计数)
这是一个例子
ID Text Other Columns...
1 Ad1 ...
2 Ad2 ...
3 Ad3 ...
4 Ad4 ...
5 Ad5 ...
6 Ad6 ...
让我们说在我的视图中,我确定我需要为用户1显示2个广告。我想要返回广告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 to Entities无法识别方法'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加载到一个Queue中,并且确实入队/出队,但是当对数据库进行更改时,这不会更新。我根据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 :(得分:0)
SkipWhile
;它无法转换为SQL代码。 EF基本上适用于集合而不是序列(我希望句子有意义)。
解决方法是简单地使用Where
,例如:
IEnumerable<Ad> Ads = db.Ads.OrderBy(x=>x.Id).Where(x=>x.Id >= NextAd.Id);
答案 1 :(得分: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;
}
抱歉,尚未对此进行测试,但它应该可以正常工作。