从DB分割成果转化的10“块”(Split results from DB into “chunks

2019-09-19 17:06发布

下午,

我需要一只手1200分的结果分割成“块” 10,所以我可以处理这些结果与亚马逊MWS API。 任何人都可以提供我怎么会去这样做,请任何指导?

 List<string> prodASIN = dc.aboProducts.Select(a => a.asin).Take(10).ToList();

我现在有这个,它的工作原理。 但我有1200+的结果和需要遍历每个10这样我就可以处理它们,并将它们传递到亚马逊MWS API

Answer 1:

为什么不尝试这样的:

//Load all the database entries into Memory
List<string> prodASINs = dc.aboProducts.Select(a => a.asin).ToList();
var count = prodASINs.Count();
//Loop through passing 10 at a time to AWS
for (var i = 0; i < count; i++)
{
    var prodASINToSend = prodASINs.Skip(i * 10).Take(10).ToList(); 
    //Send to AWS
}

或者,如果你不想将它们全部加载到内存中。

var count = dc.aboProducts.Count();
for (var i = 0; i < count; i++)
{
    List<string> prodASIN = dc.aboProducts.OrderBy(a => a.Id).Select(a => a.asin).Skip(i * 10).Take(10).ToList(); 
    //Send to AWS
}


Answer 2:

我知道这个问题的答案,但我不能对你隐瞒这一点扩展方法,我曾经提出,并已使我受益匪浅,因为。

你可以做:

foreach(var list in prodASINs.ToChunks(10))
{
    // send list
}


Answer 3:

很抱歉,这心不是LINQ特定的,但也许这将有助于...

有一个问题我已经使用数据与MWS和ERP软件将控制列到数据库中,像“addedASIN”时所做的事情。在数据库中,我定义控制列的布尔值(或TINYINT(1) MySQL的)和默认的标志为0,所有新项目并在已添加的条目将其设置为1。

如果你能做到这一点,那么你可以这样做

SELECT asin FROM datasource WHERE addedASIN = 0 LIMIT 10;

然后,一旦MWS返回成功为增加使用更新的标志

UPDATE datasource SET addedASIN = 1 WHERE asin = 'asinnumber';

我曾与此发现的好处是,你的数据库就可以停止,并开始与数据的重复最小的 - 在我的情况,例如(什么初一控制列)我们的网络连接可以是片状的,所以在我被发现为了进口我会失去连接导致订单丢失,或订单被上传到我们的系统的两倍。

该解决方案减轻了,通过具有至多1个顺序被添加两次作为连接损耗的结果,并且为了要上载的顺序两次,连接需要被丢失之间的数据发送到我们的ERP系统中,我们的ERP系统确认它,并将该数据库被更新,这对于一个往返大约需要30秒。



Answer 4:

片段扩展(阵列):

    public static T[] Slice<T>(this T[] source, int index, int length)
    {
        T[] slice = new T[length];
        Array.Copy(source, index, slice, 0, length);
        return slice;
    }

Array.Copy非常快,比选择/跳跃快得多/送模式。 虽然这种方法不禁食我发现,最近用过的测试表明,它的近400倍的速度比跳过/送用来分割清单和阵列模式。

要使用它是:

const int arraySize = 10;
List<string> listSource = whatever;
string[] source = listSource.ToArray();

for (int i = 0; i < source.Length; i += arraySize)
{
    List<string> buffer = source.Slice(i, arraySize).ToList();
    DoSomething(buffer);
}


Answer 5:

List<T>有一个叫做内置功能GetRange()这是专门为做你想要做的事。 它的速度极快,不需要LINQ中,铸造等..

List<string> prodASINs = dc.aboProducts.Select(a => a.asin).ToList(); 

for(int i = 0; i < prodASINs.Count; i += 10)
{

    List<string> buffer = prodASINs.GetRange(i, 10);
    // do something with buffer
}

而已。 很简单。


测试结果: GetRangeSliceLinq 5000个字符串List<string>正如你可以清楚地看到,跳过/送方式使用LINQ是慢了383倍Slice<T>()比和4736倍慢GetRange()

================================================== ================================

GetRange took on average 168 ticks
Slice took on average 2073 ticks
Linq took on average 795643 ticks

用试验方法(尝试一下):

private static void GetRangeVsSliceVsLinq()
{
    List<string> stringList = new List<string>();
    for (int i = 0; i < 5000; i++)
    {
        stringList.Add("This is a test string " + i.ToString());
    }

    Stopwatch sw = new Stopwatch();

    long m1 = 0, m2 = 0, m3 = 0;


    for (int x = 0; x < 10; x++)
    {
        Console.WriteLine("Iteration {0}", x + 1);
        Console.WriteLine();

        sw.Reset();
        sw.Start();

        for (int i = 0; i < stringList.Count; i += 10)
        {
            List<string> buffer = stringList.GetRange(i, 10);
        }
        sw.Stop();
        Console.WriteLine("GetRange took {0} msecs", sw.ElapsedMilliseconds);
        Console.WriteLine("GetRange took {0} ticks", sw.ElapsedTicks);
        m1 += sw.ElapsedTicks;

        sw.Reset();
        sw.Start();

        string[] sliceArray = stringList.ToArray();
        for (int i = 0; i < sliceArray.Length; i += 10)
        {
            List<string> buffer = sliceArray.Slice(i, 10).ToList();
        }
        sw.Stop();
        Console.WriteLine("Slice took {0} msecs", sw.ElapsedMilliseconds);
        Console.WriteLine("Slice took {0} ticks", sw.ElapsedTicks);
        m2 += sw.ElapsedTicks;

        sw.Reset();
        sw.Start();

        var count = stringList.Count();
        for (var i = 0; i < count; i++)
        {
            var buffer = stringList.Skip(i * 10).Take(10).ToList();
        }

        sw.Stop();
        Console.WriteLine("Skip/Take took {0} msecs", sw.ElapsedMilliseconds);
        Console.WriteLine("Skip/Take took {0} ticks", sw.ElapsedTicks);
        m3 += sw.ElapsedTicks;

        Console.WriteLine();
    }

    Console.WriteLine();
    Console.WriteLine("GetRange took on average {0} ticks", m1 / 10);
    Console.WriteLine("Slice took on average {0} ticks", m2 / 10);
    Console.WriteLine("Linq took on average {0} ticks", m3 / 10);

}


文章来源: Split results from DB into “chunks” of 10