ASP.NET 2.0 C# DAL 多变量参数

发布于 2024-10-27 05:26:36 字数 948 浏览 8 评论 0原文

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

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

然而,我一直在阅读有关使用 BLL 和 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 不应与调用它的类共享任何引用?

感谢您就如何实现此场景提供任何建议。

I'm developing a Web App designed to query a large database table based on the users selection of criteria. In some cases, they may know and enter the primary key, other times they might want to see records of status abc created in the last 7 days, or records created by fred smith where the description contains the word proposal.
The point is, there could easily be 10 - 20 different variables that they could specify, based on what they're looking for.

It's easy enough for me to build the SQL statement and apply the parameters dynamically in the code behind the webpage (aspx.cs). This approach works well.

However, I've been reading up on using a BLL & DAL (or even just a DAL) but all the examples I've seen have been trivial with no parameters eg getCategories() or a single parameter eg getProductByID(int productID)

So what I'd like advice on is how best to pass my variable list of many parameters to the BLL/DAL without having a method with (eg) 20 parameters (this is workable but seems hugely unwieldly, especially if a new selection parameter is added).

The other ideas I've thought of are

  1. Build a single string parameter that can be decoded in the method, eg:
string params = "DateField=Created;FromDate=2011-03-01;Status=abc"  
BLL.getRecords(params);  

(Workable, but horrible and prone to mistakes)

  1. Use a struct or a class as the parameter, eg
params.Status = "abc";  
params.createdByUser = 23; 

Is there an issue with the DAL having access to this struct/class? I've read that the DAL should not share any references with the classes that call it?

Thanks for any suggestions as to how you would implement this scenario.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

深居我梦 2024-11-03 05:26:36

在我的项目中,我创建了静态类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];
}

正如您在数据库中看到的那样,我们只有一个存储过程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

这种方法可以轻松添加新的过滤请求

In my projects I create static class DataManager that exposes all required functions for obtaining data, e.g.

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];
}

As you see in DB we have only one stored procedure GetActionHistoryList (for ActionHistory table data) with many different arguments.
Stored procedure contains dynamic SQL e.g.

`<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

Such approach allows easily to add new filtering requests

莫相离 2024-11-03 05:26:36

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

另一种选择是使用 LINQ-to-SQL。然后,您可以直接将该表公开为 IQueryable。然后,客户端代码可以完全自由地根据需要过滤表。

You could create an ISearchOption interface that supplies the necessary options to the DAL. You can provide common overloads to GetRecords(ISearchOption options) that construct an internal ISearchOption instance and pass it to the GetRecords() overload.

Another option would be to use LINQ-to-SQL. You could then expose the table as an IQueryable directly. Client code then has complete freedom to filter the table as needed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文