通过DBSET迭代以获取下一个n行



我正在尝试找出通过各种函数呼叫连续迭代的好方法,最后一次循环。

本质上,我在数据库中有很多广告,我想在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;
}

对不起,还没有测试过,但是应该起作用。

最新更新