简体   繁体   English

遍历dbset以获取下n行

[英]Iterate through dbset to get next n rows

I'm trying to find out what's a good way to continually iterate through a dbset over various function calls, looping once at the end. 我试图找出什么是在各种函数调用上连续遍历dbset的好方法,最后循环一次。

Essentially I've got a bunch of Ads in the database, and I want to getNext(count) on the dbset.Ads 本质上,我在数据库中有一堆广告,并且我想在dbset上获取Next(count)。

Here's an example 这是一个例子

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

Let's say that in my View, I determine I need 2 ads to display for User 1. I want to return Ads 1-2. 假设在“视图”中,我确定需要为用户1显示2个广告。我希望返回1-2个广告。 User 2 then requests 3 ads. 然后,用户2请求3个广告。 I want it to return 3-5. 我希望它返回3-5。 User 3 needs 2 ads, and the function should return ads 6 and 1, looping back to the beginning. 用户3需要2个广告,并且该功能应返回广告6和1,并循环回到开头。

Here's my code that I've been working with (it's in class AdsManager ): 这是我一直在使用的代码(位于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;
}

The problem is that the function call IEnumerable<Ad> Ads = db.Ads.OrderBy(x=>x.Id).SkipWhile(x=>x.Id != NextAd.Id); 问题是该函数调用IEnumerable<Ad> Ads = db.Ads.OrderBy(x=>x.Id).SkipWhile(x=>x.Id != NextAd.Id); throws an error on AddRange(Ads) : AddRange(Ads)上引发错误:

LINQ to Entities does not recognize the method '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]])' method, and this method cannot be translated into a store expression. 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]])方法,该方法无法转换为商店表达式。

I originally had loaded the entire dbset into a Queue, and did enqueue/dequeue, but that would not updat when a change was made to the database. 我最初将整个dbset加载到队列中,并进行了入队/出队,但这在对数据库进行更改时不会更新。 I got the idea for this algorithm based on Get the next and previous sql row by Id and Name, EF? 我通过基于ID和名称EF获取下一个和上一个sql行,对这种算​​法有了想法

What call should I be making to the database to get what I want? 我应该对数据库进行什么调用才能得到我想要的?

UPDATE: Here's the working Code: 更新:这是工作代码:

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 is not supported in the EF; EF不支持SkipWhile it can't be translated into SQL code. 无法将其转换为SQL代码。 EF basically works on sets and not sequences (I hope that sentence makes sense). EF基本上适用于集合而不是序列(我希望这句话有意义)。

A workaround is to simply use Where , eg: 一种解决方法是简单地使用Where ,例如:

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

Maybe you can simplify this into something like this: 也许您可以将其简化为以下形式:

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;
}

Sorry, haven't tested this, but it should work. 抱歉,尚未测试,但应该可以。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM