0

我正在开发一个 Web 应用程序,旨在根据用户选择的条件查询大型数据库表。在某些情况下,他们可能知道并输入主键,有时他们可能希望查看abc过去 7 天内创建的状态记录,或者fred smith在描述中包含单词的位置创建的记录proposal。关键是,根据他们正在寻找的内容,他们可以轻松指定 10 到 20 个不同的变量。

构建 SQL 语句并在网页后面的代码中动态应用参数对我来说很容易 ( aspx.cs)。这种方法效果很好。

但是,我一直在阅读有关使用 BLL 和 DAL(甚至只是 DAL)的内容,但我所看到的所有示例都是微不足道的,没有参数,例如getCategories()或单个参数,例如getProductByID(int productID)

所以我想要建议的是如何最好地将我的许多参数的变量列表传递给 BLL/DAL,而无需使用具有(例如)20 个参数的方法(这是可行的,但看起来非常笨拙,特别是如果一个新的选择参数是添加)。

我想到的其他想法是

  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

您可以创建一个ISearchOption接口,为 DAL 提供必要的选项。您可以GetRecords(ISearchOption options)为该构造提供常见的重载 ISearchOption 实例并将其传递给GetRecords()重载。

另一种选择是使用 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(用于表数据)。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 回答