0

Linq を使用して 2 つのコレクションを結合する開発シナリオがあります。プレゼンテーション メタデータを含む列ヘッダー オブジェクトの 1 つのリストと、Web サービス呼び出しの結果として得られる kv 辞書の列挙。現在、ディクショナリの列挙を反復処理 ( for) し、単一のヘッダー リストを現在の kv ディクショナリに問題なく結合できます。参加後、反復ごとにキュレートされたディクショナリ値の配列を出力します。

私がやりたいことは、forループを排除し、単一のヘッダー リストを列挙全体に直接結合することです。1 対 1 のコレクションの結合についてはよく理解していますが、1 対 N の構文はわかりません。

詳細

私は次の作業方法を持っています:

public void GetQueryResults(DataTable outputTable)
{
    var odClient = new ODataClient(UrlBase);
    var odResponse = odClient.FindEntries(CommandText);

    foreach (var row in odResponse)
    {
        var rowValues = OutputFields
            .Join(row, h => h.Key, r => r.Key, 
                (h, r) => new { Header = h, ResultRow = r })
            .Select(r => r.ResultRow.Value);

        outputTable.Rows.Add(rowValues.ToArray());
    }
}

odResponseを含むIEnumerable<IDictionary<string, object>>; OutputFieldsを含むIList<QueryField>; 一致したフィールド メタデータ ( ) と応答 kv ペア ( ) を含むアノンの.Join列挙を生成します。最後に、行の消費に対して一致した応答値を発行します。コレクションは次のようになります。.Header.ResultRow.SelectOutputField

class QueryField
{
    public string Key { get; set; }
    public string Label { get; set; }
    public int Order { get; set; }
}

次のように宣言されています。

public IList<QueryField> OutputFields { get; private set; }

フィールド ヘッダーのコレクションを応答行に結合することで、応答から必要な列だけを取り出すことができます。ヘッダー キーに { "size", "shape", "color" } が含まれ、応答キーに { "size", "mass", "color", "longitude", "latitude" } が含まれている場合、配列を取得します{ "size", "shape", "color" } の値。 shapeは null で、masslongitude、およびlatitudeの値は無視されます。このシナリオでは、注文については考慮しません。これはすべて御馳走になります。

問題

私がやりたいのは、このメソッドをリファクタリングして値配列行の列挙を返し、呼び出し元がデータの消費を管理できるようにすることです。

public IEnumerable<string[]> GetQueryResults()
{
    var odClient = new ODataClient(UrlBase);
    var odResponse = odClient.FindEntries(CommandText);

    var responseRows = //join OutputFields to each row in odResponse by .Key

    return responseRows;
}

フォローアップの質問

このリファクタリング用に Linq で実装されたソリューションでは、列挙型をすぐにスキャンする必要がありますか?それとも遅延結果を返すことができますか? リファクタリングの目的は、冗長なコレクション スキャンを発生させずにカプセル化を改善することです。難しい方法で応答データを再フォーマットする命令型ループをいつでも作成できますが、Linq に求めているのはクロージャーのようなものです。

これを読むために時間を費やしてくれてありがとう。どんな提案でも大歓迎です!

4

1 に答える 1