3

まず、環境に関するいくつかの背景情報...

Windows の「クライアント」と Linux の「サーバー」の 2 つのマシンがあります。

  1. Windows 2008 R2 x64 • IIS 7.5 • NET 3.5 • SharePoint 2010 • Visual Studio 2010 • IBM DB2 .NET データ プロバイダー ランタイム バージョン v4.0.30319、ドライバー バージョン 9.7.4.4。
  2. RedHat Linux、IBM DB2 データベース バージョン 9.5.3*。

* IBM の Web サイトで概説されている推奨される解決策は、クライアントを 9.7 FP5 にアップグレードすることです。これを試し、バージョン 10 にアップグレードしましたが、それでも同じエラーが発生しました。この記事の著者が、サーバー上で実行されている実際のデータベースバージョンをアップグレードする必要があると言及している場合、これは現時点で私の顧客にとって受け入れられる解決策ではないため、問題を引き起こします。

私は LINQ-to-Entities の使用に固執しているわけではなく、現在それに依存している既存のコードの膨大な部分を書き直す必要がなければ、互換性のある代替手段を歓迎します。

さて、問題に…</p>

以下は、実行しようとしているコードです。クエリで使用される caseid パラメータに注意してください。

public List<JqueryAutocompleteEntity> Cases(string caseid)
{
    var query = (from c in context.ASSET_T
                             where c.CA_ID_AGCY.StartsWith(caseid.Trim().ToUpper())
                             select new JqueryAutocompleteEntity
                                        {
                                            id = c.CA_ID_AGCY.Trim(),
                                            label = c.CA_ID_AGCY.Trim(),
                                            value = c.CA_ID_AGCY.Trim()
                                        }).Distinct().Take(10);
    return query.ToList();
}

上記のコードが実行時に実行されると、次の例外がスローされます。

コマンド定義の実行中にエラーが発生しました。詳細については、内部例外を参照してください。IBM.Data.DB2.DB2Exception: ERROR [42815] [IBM][DB2/LINUXX8664] SQL0171N ルーチン「SYSIBM.STRIP」の位置「string-expr」にあるパラメーターの引数のデータ・タイプ、長さ、または値が正しくありません. パラメータ名: "". IBM.Data.DB2.DB2Command.ExecuteReaderObject(CommandBehavior 動作、文字列メソッド、DB2CursorType reqCursorType、Boolean abortOnOptValueChg、Boolean skipDeleted、Boolean isResultSet、Int32 maxRows、Boolean skipInitialValidation) で IBM.Data.DB2.DB2Command.ExecuteReaderObject(CommandBehavior 動作、文字列)メソッド) で IBM.Data.DB2.DB2Command.ExecuteReader(CommandBehavior 動作) で IBM.Data.DB2.DB2Command.ExecuteDbDataReader(CommandBehavior 動作) で System.Data。

これは、LINQ-to-Entities によって生成された SQL ステートメントであり、DB2 データベース内の Linux サーバーで実行するために .NET DB2 ドライバーに渡されます。

SELECT CAST(1 AS int) AS C1、STRIP(Extent1.CA_ID_AGCY,BOTH) AS C2、STRIP(Extent1.CA_ID_AGCY,BOTH) AS C3、STRIP(Extent1.CA_ID_AGCY,BOTH) AS C4 FROM ASSET_T AS Extent1 WHERE (LOCATE( UPPER(STRIP(@p_ linq _1,BOTH)), Extent1.CA_ID_AGCY)) = CAST(1 AS int)

ご覧のとおり、実際の値で置き換える代わりに、最終的な SQL ステートメントを生成するときに、パラメーター/変数の名前が使用されたようです。さらに、LINQ クエリに値をハード コーディングしても、実際には問題なく動作します。

c.CA_ID_AGCY.StartsWith(“test”.Trim().ToUpper()) <= これは機能します!!!

LINQ クエリの最初の部分で .AsEnumerable() 拡張を使用しようとしたので、すべてのデータをメモリにロードしてから、パラメーターを使用してフィルターを実行できますが、結果セットが WAY だったため、このアプローチは明らかに機能しませんでした大きすぎます (つまり、数百万のレコード)。サーバーのCPUを殺してしまい、RAMを使い果たします。データベースに対して直接クエリを実行し、foreach ループを使用して JQueryAutocompleteEntity オブジェクトのコレクションを設定することにより、単純な「実証済み」の DataReader/DataTable アプローチで必要なことを明らかに達成できますが、より洗練されたソリューションを使用することをお勧めします。 LINQ-to-Entities と同様に、foreach ループでリストにデータを入力する追加の実行時間を無駄にしないようにします。

これらすべてについて私が非常に厄介だと思うのは、パラメーター化されたクエリのサポートが非常に明白な機能のように見えることです。任意の言語でコーディングするときに、変数よりも定数をどのくらいの頻度で使用しますか?

カスタム動的クエリ ライブラリに関するScott Guthrie のブログ投稿は、私の問題の回避策を提供しているように見えますが、完全には解決していません。

この問題を (.NET Framework または DB2 をアップグレードする必要なく) 解決するための支援をいただければ幸いです。

ありがとう!

4

0 に答える 0