0

ユーザーの選択した基準に基づいて大規模なデータベース テーブルをクエリするように設計された Web アプリを開発しています。主キーを知っていて入力する場合もあればabc、過去 7 日間に作成されたステータスのレコードやfred smith、説明に と​​いう単語が含まれる によって作成されたレコードを見たい場合もありproposalます。ポイントは、彼らが探しているものに基づいて、指定できる 10 から 20 の異なる変数が簡単に存在する可能性があるということです。

SQL ステートメントを作成し、Web ページの背後にあるコードでパラメーターを動的に適用するのは簡単です ( aspx.cs)。このアプローチはうまく機能します。

ただし、BLL と DAL (または単なる DAL) の使用について調べてきましたが、これまでに見たすべての例は、パラメーターなしgetCategories()、または単一パラメーターなどの単純なものでした。getProductByID(int productID)

したがって、アドバイスが欲しいのは、(たとえば) 20 個のパラメーターを持つメソッドを使用せずに、多くのパラメーターの変数リストを BLL/DAL に渡す最善の方法です (これは実行可能ですが、特に新しい選択パラメーターが追加した)。

私が考えた他のアイデアは

  1. メソッドでデコードできる単一の文字列パラメータを作成します。例:
string params = "DateField=Created;FromDate=2011-03-01;Status=abc"  
BLL.getRecords(params);  

(実行可能ですが、恐ろしく、間違いを起こしやすい)

  1. パラメータとして構造体またはクラスを使用します。
params.Status = "abc";  
params.createdByUser = 23; 

この構造体/クラスにアクセスできる DAL に問題はありますか? DAL はそれを呼び出すクラスと参照を共有すべきではないことを読みましたか?

このシナリオをどのように実装するかについての提案に感謝します。

4

2 に答える 2

0

ISearchOptionDALに必要なオプションを提供するインターフェースを作成できます。GetRecords(ISearchOption options)内部ISearchOptionインスタンスを構築するための一般的なオーバーロードを提供し、それをGetRecords()オーバーロードに渡すことができます。

もう1つのオプションは、LINQ-to-SQLを使用することです。次に、テーブルをIQueryableとして直接公開できます。クライアントコードは、必要に応じてテーブルをフィルタリングする完全な自由を持っています。

于 2011-03-28T01:42:53.930 に答える
0

私のプロジェクトではDataManager、データを取得するために必要なすべての関数を公開する静的クラスを作成します。

public static IList<ActionHistoryData> GetActionHistoryList(DateTime startDate, DateTime endDate, bool postprocessed)
{
   return GlobalComponents.DataManagerImpl.GetActionHistoryList(null, null, null, null, null, null, null, startDate, endDate, false, postprocessed, null);
}

public static ActionHistoryData GetActionHistory(int id)
{
    IList<ActionHistoryData> actionHistoryList =
        GlobalComponents.DataManagerImpl.GetActionHistoryList(id, null, null, null, null, null, null, null, null, null, null, null);
    CQGUtils.Verify(!CollectionsUtil.IsEmpty(actionHistoryList), "There is no action history with [ID='{0}']", id);
    CQGUtils.Verify(actionHistoryList.Count == 1, "More than one action history returned.");
    return actionHistoryList[0];
}

DB でわかるように、多くの異なる引数を持つGetActionHistoryList(テーブル データ用の) ストアド プロシージャは 1 つだけです。ActionHistoryストアド プロシージャには動的 SQL が含まれています。

`<select statement part>`

DECLARE @where nvarchar(4000);
SET @where = N' WHERE '
IF @ID IS NOT NULL
    SET @where = @where + '(ah.ID = @ID) AND '
IF @AccountID IS NOT NULL
    SET @where = @where + '(ah.AccountID = @AccountID) AND '
IF @SourceKind IS NOT NULL
    SET @where = @where + '(ah.SourceKind = @SourceKind) AND '
IF @SourceIDArray IS NOT NULL
    SET @where = @where + '(ah.SourceID IN ('+ @SourceIDArray +')
IF @Postprocessed IS NOT NULL
    SET @where = @where + '(ah.Postprocessed = @Postprocessed) AND '
IF @StartDate IS NOT NULL
    SET @where = @where + '(ah.UtcTimestamp >= @StartDate) AND '
IF @EndDate IS NOT NULL
    SET @where = @where + '(ah.UtcTimestamp <= @EndDate) AND '
) AND '

SET @where = @where + ' 1=1'
SET @query = @query+@where+' order by utcTimestamp desc '

EXEC sp_executesql @query,
N'
    @ID int,
    @AccountID int,
    @SourceKind tinyint,
    @SourceIDArray nvarchar(max),
    @NotificationID int,
    @DataRequestID int,
    @NotificationName nvarchar(250),
    @StartDate datetime,
    @EndDate datetime,
    @MostRecent bit,
    @Postprocessed bit,
    @TopLimit int
',
@ID = @ID,
@AccountID = @AccountID,
@SourceKind = @SourceKind,
@SourceIDArray = @SourceIDArray,
@NotificationID = @NotificationID,
@DataRequestID = @DataRequestID,
@NotificationName = @NotificationName,
@StartDate = @StartDate,
@EndDate = @EndDate,
@MostRecent = @MostRecent,
@Postprocessed = @Postprocessed,
@TopLimit = @TopLimit

このようなアプローチにより、新しいフィルタリング要求を簡単に追加できます

于 2011-03-27T18:53:24.610 に答える