0

    評価する書類番号のリストがあります。このリストは非常に大きく、文字を含めることもできるため、すべてのドキュメント番号をintにキャストすることは避けたいと思います。これが数字のサンプルリストです。

1070
1071
1072
1073
1074
1075
1076
1077
1078
CO1089
CO1099
CO2000

    これらの番号はC#のオブジェクトに含まれており、Linqを実行して範囲内のオブジェクトのリストを返します。これが私のlinqコードです。

results = from row in MyObjectList.AsQueryable<MyObject>()
          where String.Compare(row.Header.DocNumber, _sDocumentStartNumber) >= 0 
          && String.Compare(row.Header.DocNumber, _sDocumentEndNumber) <= 0
          select row;



From: 1
To:       10000の範囲がある場合

    ユーザーは、その範囲内のすべての数値トランザクションを取り戻すことを期待します。ただし、文字列を比較しているため、結果が返されません。

    toとfromの値が数値であることを検出し、数値のあるトランザクションのみを評価し、それに基づいてlinqステートメントを使用する(またはlinqステートメントを編集して変換と比較を行う)ことができましたが、この時点ではパフォーマンスに関心があります。戻るとき、リストはかなり大きくなる可能性があります。

    私はここで提案を受け入れており、すべて同じ結果につながる多くの道があるかもしれないことを知っています。これに関する私の主な関心事はパフォーマンスです。非常に大きなデータセットに対してこのアクションを実行する可能性があり、妥当な時間内に結果を返す必要があることを忘れないでください。

ありとあらゆる提案を事前に感謝します。

~~~編集~~~

追加情報

    私が活用しているオブジェクトは、QuickBooksOnline用のIntuitIPPSDKオブジェクトです。intuitにドキュメント(請求書など)を照会していますが、ドキュメント番号で並べ替える必要があります。Intuitはサーバー側でこれを行わないので、私は自分の側でこれを行う必要があります。ユーザーが他の検索条件に入力した内容によっては、返されたリストにすべてのドキュメントが含まれる可能性があります。

4

2 に答える 2

1

独自の比較ツールを作成しますDocumentNumberWithinRangeComparer

public class DocumentNumberWithinRangeComparer
{
    public int? RangeFrom { get; set; }
    public int? RangeTo { get; set; }

    public DocumentNumberWithinRangeComparer(int? from, int? to)
    {
        RangeFrom = from;
        RangeTo = to;
    }

    public bool IncludeInResults(MyObject obj)
    {
        if (!RangeTo.HasValue || !RangeFrom.HasValue)
            return true;

        int docnumber;
        if (!Int32.TryParse(obj.Header.DocNumber, out docnumber))
            return false;

        return docnumber >= RangeFrom.Value && docnumber <= RangeTo.Value;
    }
}

次に、そのインスタンスを作成し、それを使用してフィルタリングします。

var comparer = new DocumentNumberWithinRangeComparer(0,100);
var results = from row in MyObjectList.AsQueryable<MyObject>()
              where comparer.IncludeInResults(row)
              select row;

より高速な比較が必要な場合は、「DocNumber」を整数に前処理する必要がありますが、これは、ドキュメントのリストを1回処理してから、複数回クエリする場合にのみ意味があります。


前処理の簡単な解決策は、Dictionary<string, int>fromHeader.DocNumber文字列値と解析された数値を作成することです。解析しない値の場合は、、などを使用するか-1Int32.MinValue数値以外の値を処理できるより高度なパーサーを作成できます。

辞書ができたら、次のようにクエリできます...

var dictionary = new Dictionary<string, int>(); // Fill this...
var results = from row in MyObjectList.AsQueryable<MyObject>()
              where dictionary[row.Header.DocNumber] >= _sDocumentStartNumber &&
                    dictionary[row.Header.DocNumber] <= _sDocumentEndNumber 
              select row;

この辞書の設定には余分な時間がかかりますが、同じドキュメントセットを複数回クエリすると、効果があります。

于 2013-03-06T16:26:30.643 に答える
0

範囲を取得したら、開始番号の左側にスペースを埋め込んで、終了番号と同じ長さにします。したがって、あなたの例では、終了番号は「10000」です。したがって、最初の数字を「_ _1」 (つまり、4 つのスペースと 1) にします。

比較するときは、比較する前にドキュメント番号を左パディングします。そう:

string paddedStart = _sDocumentStartNumber.PadLeft(_sDocumentEndNumber.Length);
string padded;
results = from row in MyObjectList.AsQueryable<MyObject>()
      let padded = row.Header.DocNumber.PadLeft(paddedStart.Length)
      where String.Compare(padded, paddedStart) >= 0 
          && String.Compare(padded, _sDocumentEndNumber) <= 0
      select row;
于 2013-03-06T16:26:51.000 に答える