web-dev-qa-db-ja.com

LINQで文字列比較を行う際の問題

LINQで何かを必要なクエリに変換するのに問題があります。 T-SQLでは、CHAR(6)列である3つの列に対して<=と> =の比較を行います。 LINQでは、これを実行できません。

演算子 '<='は、タイプ 'string'から 'string'のオペランドには適用できません。

次のT-SQLクエリがあります。

SELECT * 
FROM [ZIPMASTER] zm
WHERE zm.CORP = 12 
AND '85546 ' BETWEEN zm.ZIPBEG AND zm.ZIPEND

BETWEENはサポートされていないため、上記はあまりLINQではありません。したがって、私は次のように簡略化しました。

SELECT *
FROM [ZIPMASTER] zm
WHERE zm.CORP = 12
AND zm.ZIPBEG <= '85546 '
AND zm.ZIPEND >= '85546 '

次のLINQクエリを作成するために使用しました。

var zipLinqQuery =
    from z in db.ZIPMASTERs
    where z.CORP == 12
    && z.ZIPBEG <= "85546 "
    && z.ZIPEND >= "85546 "
    select z;
List<ZIPMASTER> zips = zipLinqQuery.ToList<ZIPMASTER>();

C#-LINQはこのクエリをあまり好きではありません。 intに変換して比較してみましたが、郵便番号に文字が含まれている場合があります。たとえば、次の式はT-SQLでtrueと評価されます。

WHERE '85546B' BETWEEN '85546A' AND '85546D'

T-SQLで機能する理由は正確にはわかりませんが、配列内の各文字を数値ASCII値に変換することにより、個別に比較していると思います。

とにかく、あなたが提供できるどんな助けも大いに感謝されます。前もって感謝します。

CJAM

解決策(Jon Skeetによる投稿):

String.CompareTo()は実際に必要なT-SQLを生成しているようです。以下の例:

var zipLinqQuery =
    from z in db.ZIPMASTERs
    where z.CORP == listItem.CORP
    && z.ZIPBEG.CompareTo(listItem.ZIPCODE) <= 0
    && z.ZIPEND.CompareTo(listItem.ZIPCODE) >= 0
    select z;

次のT-SQLを生成します。

DECLARE @p0 INT, @p1 CHAR(6), @p2 CHAR(6)
SET @p0 = 12
SET @p1 = '85546 '
SET @p2 = '85546 '

SELECT [t0].[CORP], [t0].[ZIPEND], [t0].[ZIPBEG], [t0].[CITY], [t0].[STATE], [t0].[CYCLE]
FROM [dbo].[ZIPMASTER] AS [t0]
WHERE ([t0].[CORP] = @p0) AND ([t0].[ZIPBEG] <= @p1) AND ([t0].[ZIPEND] >= @p2)
25
regex

試してみてください:

var zipLinqQuery =
    from z in db.ZIPMASTERs
    where z.CORP == 12
    && z.ZIPBEG.CompareTo("85546 ") <= 0
    && z.ZIPEND.CompareTo("85546 ") >= 0
    select z;

String.CompareToがLINQto SQLで機能することを知らないが、最初に試すことです。

(通常、StringComparerを使用して適切なタイプの比較を指定する必要がありますが、この場合はCompareToの方が適していると思います。)

39
Jon Skeet