2

午後、

Amazon MWS APIでこれらの結果を処理できるように、1200を超える結果を10の「チャンク」に分割するための手が必要です。誰かが私がこれをどのように行うかについてのガイダンスを提供できますか?

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

私は現在これを持っています、それはうまくいきます。しかし、1200以上の結果があり、10個ごとにループして、それらを処理してAmazonMWSAPIに渡すことができるようにする必要があります。

4

5 に答える 5

2

私は質問が答えられることを知っています、しかし私はあなたから私がかつて作ったこの小さな拡張方法を差し控えることができません、そしてそれはそれ以来私によく役立ちました。

できるよ:

foreach(var list in prodASINs.ToChunks(10))
{
    // send list
}
于 2012-07-21T21:00:51.783 に答える
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
}
于 2012-07-18T13:23:40.050 に答える
1

申し訳ありませんが、これはLINQ固有ではありませんが、おそらく役立つでしょう...

MWSおよびERPソフトウェアでデータを操作するときに行ったことの1つは、「addedASIN」のような制御列をデータベースに追加することです。データベースでは、制御列をブール値(またはTINYINT(1) MySQL)、デフォルトですべての新しいエントリのフラグを0に設定し、エントリが追加されたら1に設定します。

あなたがそれをすることができるなら、あなたは次のようなことをすることができます

SELECT asin FROM datasource WHERE addedASIN = 0 LIMIT 10;

次に、MWSが追加に成功した場合は、次を使用してフラグを更新します。

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

これで私が見つけた利点は、データベースが最小限のデータの繰り返しで停止および開始できることです-たとえば、私の場合(およびこのコントロール列を開始したもの)、ネットワーク接続が不安定になる可能性があるため、注文のインポート接続が失われると、注文が失われるか、注文がシステムに2回アップロードされます。

このソリューションは、接続が失われた結果として最大1つの注文が2回追加され、その注文が2回アップロードされるためには、データをERPシステム(ERPシステム)に送信する間に接続が失われる必要があることを軽減しました。それが追加され、データベースが更新されたことを確認します。これには、往復で約30秒かかります。

于 2012-07-18T13:32:19.890 に答える
0

スライス拡張(配列用):

    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は非常に高速で、Select / Skip/Takeパターンよりもはるかに高速です。この方法は私が見つけた断食ではありませんが、最近のテストでは、リストと配列の分割に使用されるスキップ/テイクパターンよりも約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);
}
于 2012-07-18T13:34:16.670 に答える
-1

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
}

それでおしまい。とてもシンプルです。


テスト結果:vs。vs GetRange.で5000文字列を 使用する場合明らかなように、Linqを使用したSkip / Takeアプローチは、383倍以上遅く、4,736倍遅くなります。SliceLinqList<string>Slice<T>()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);

}
于 2012-07-22T13:50:48.177 に答える