これよりももう少しエレガントなものがあればいいのにと思います。これは私のストアド プロシージャ ソリューションです。私の不完全な SQL スキルが呼び起こすことができる最高のもの。
パラメーター リストの OUT パラメーターは、このセットの合計行に対するものであるため、フロント エンドは、この特定のフィルター セットと一緒に何ページかを認識します。
CREATE PROC [dbo].[procCampaignGEDPushSelect]
@LastName VARCHAR(50) = null
,@FirstName VARCHAR(50) = null
,@Location VARCHAR(255) = null
,@DoB DateTime = null
,@Zip VARCHAR(50) = null
,@Phone VARCHAR(50) = null
,@Email VARCHAR(255) = null
,@Gender VARCHAR(20) = null
,@IsGED Bit = 0
,@IsBTT Bit = 0
,@IsOACE Bit = 0
,@Completed Bit = 0
,@TotalCount INT OUT
AS
BEGIN
SELECT @LastName = @LastName + '%'
SELECT @FirstName = @FirstName + '%'
SELECT @Location = @Location + '%'
SELECT @Zip = @Zip + '%'
SELECT @Phone = @Phone + '%'
SELECT @Email = @Email + '%'
SELECT @Gender = @Gender + '%'
SELECT row_number() OVER (ORDER BY LastName, FirstName, DoB) AS RowNumber
, TPT.LastName
, TPT.FirstName
, TPT.WF1Site
, TPT.DOB
, TPT.Zip
, TPT.Telephone
, TPT.CellPhone
, TPT.Email
, TPT.Gender
, TPT.IsBTT
, TPT.IsGED
, TPT.IsOACE
, TPT.IsSRS
,CGP.*
FROM tblCampaignGEDPush CGP
JOIN tblParticipants TPT
ON CGP.PartID = TPT.PartID
WHERE 1=1
AND 1 = (CASE WHEN @LastName IS NOT NULL THEN (CASE WHEN TPT.LastName LIKE @LastName THEN 1 ELSE 0 END) ELSE 1 END)
AND 1 = (CASE WHEN @FirstName IS NOT NULL THEN (CASE WHEN TPT.FirstName LIKE @Firstname THEN 1 ELSE 0 END) ELSE 1 END)
AND 1 = (CASE WHEN @Location IS NOT NULL THEN (CASE WHEN TPT.WF1Site LIKE @Location THEN 1 ELSE 0 END) ELSE 1 END)
AND 1 = (CASE WHEN @Zip IS NOT NULL THEN (CASE WHEN TPT.Zip LIKE @Zip THEN 1 ELSE 0 END) ELSE 1 END)
AND
( 1 = (CASE WHEN @Phone IS NOT NULL THEN (CASE WHEN TPT.Telephone LIKE @Phone THEN 1 ELSE 0 END) ELSE 1 END)
OR 1 = (CASE WHEN @Phone IS NOT NULL THEN (CASE WHEN TPT.CellPhone LIKE @Phone THEN 1 ELSE 0 END) ELSE 1 END)
)
AND 1 = (CASE WHEN @Email IS NOT NULL THEN (CASE WHEN TPT.Email LIKE @Email THEN 1 ELSE 0 END) ELSE 1 END)
AND 1 = (CASE WHEN @Gender IS NOT NULL THEN (CASE WHEN TPT.Gender LIKE @Gender THEN 1 ELSE 0 END) ELSE 1 END)
AND 1 = (CASE WHEN @DoB IS NOT NULL THEN (CASE WHEN TPT.DoB = @DoB THEN 1 ELSE 0 END) ELSE 1 END)
AND 1 = (CASE WHEN @IsGED != 0 THEN (CASE WHEN TPT.IsGED = 1 THEN 1 ELSE 0 END) ELSE 1 END)
AND 1 = (CASE WHEN @IsBTT != 0 THEN (CASE WHEN TPT.IsBTT = 1 THEN 1 ELSE 0 END) ELSE 1 END)
AND 1 = (CASE WHEN @IsOACE != 0 THEN (CASE WHEN TPT.IsOACE = 1 THEN 1 ELSE 0 END) ELSE 1 END)
AND 1 = (CASE WHEN @Completed != 0 THEN (CASE WHEN CGP.Completed = 1 THEN 1 ELSE 0 END) ELSE 1 END)
ORDER BY TPT.LastName
, TPT.FirstName
, TPT.DoB
SELECT @TotalCount = @@ROWCOUNT
END
それで、私は考え始めました。私は .NET を使用しているので、このトリッキーでバグが発生しやすい proc (ちなみに、これはかなりうまく機能します) を使用するのではなく、適切な解決策があるかどうか疑問に思います。
元の質問が .NET とは何の関係もないことがわかったので、厳密な SQL ソリューションに関心のある人のために、上記の手順を残します。これはかなりうまく機能すると思います。
そこで、私は IQueryable インターフェイスを掘り下げ始め、ゴールドを獲得しました。
IQueryable<queryParticipant> qparticipant = db.queryParticipants.AsQueryable();
...
qparticipant = qparticipant.Where( ... any filter you choose );
...
return qparticipant
.OrderBy( p => p.LastName )
.OrderBy( p => p.FirstName )
.OrderBy( p => p.DOB )
.Select( ... whatever you like ... )
.Skip( StartRecordNumber ) // This is the trick! Start the query here..
.Take( PageSize ) // Take only as many as you need
;
以上です。.NET アプローチは、利用できる場合に便利です。Stored Proc は、そのような API が利用できない場合に最適です。