ASP.NET 2.0 C # DAL Параметры нескольких переменных - PullRequest
0 голосов
/ 27 марта 2011

Я разрабатываю веб-приложение, предназначенное для запроса большой таблицы базы данных на основе выбора критериев пользователями. В некоторых случаях они могут знать и вводить первичный ключ, в других случаях они могут захотеть увидеть записи статуса «abc», созданные за последние 7 дней, или записи, созданные «fred smith», где в описании содержится слово «предложение». Дело в том, что они могут легко указать 10–20 различных переменных в зависимости от того, что они ищут.

Мне достаточно легко создать оператор sql и динамически применить параметры в коде за веб-страницей (aspx.cs). Этот подход хорошо работает.

Тем не менее, я читал об использовании BLL & DAL (или даже просто DAL), но все примеры, которые я видел, были тривиальными без параметров, например, getCategories () или одного параметра, например, getProductByID (int ProductID)

Итак, я хотел бы посоветовать, как лучше всего передать мой список переменных со многими параметрами в BLL / DAL, не имея метода с (например) 20 параметрами (это выполнимо, но кажется громоздким, особенно если новый добавлен параметр выбора).

Другие идеи, о которых я подумал:

a) Создает однострочный параметр, который можно декодировать в методе, например:
string params = "DateField = Created; FromDate = 2011-03-01; Status = abc"
BLL.getRecords (PARAMS);
(Работоспособный, но ужасный и подверженный ошибкам) ​​

b) Использовать структуру или класс в качестве параметра, например,
params.Status = "abc";
params.createdByUser = 23;

(Есть ли проблема с DAL, имеющим доступ к этой структуре / классу? Я читал, что DAL не должен делиться ссылками с классами, которые его вызывают?

Спасибо за любые предложения относительно того, как бы вы реализовали этот сценарий.

Ответы [ 2 ]

0 голосов
/ 28 марта 2011

Вы можете создать интерфейс ISearchOption, который предоставляет необходимые опции для DAL. Вы можете предоставить общие перегрузки для GetRecords(ISearchOption options), которые создают внутренний экземпляр ISearchOption и передать его перегрузке GetRecords().

Другой вариант - использовать LINQ-to-SQL. Затем вы могли бы выставить таблицу как IQueryable напрямую. Клиентский код тогда имеет полную свободу фильтровать таблицу по мере необходимости.

0 голосов
/ 27 марта 2011

В моих проектах я создаю статический класс 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 (для * 1006).* таблица данных) с множеством разных аргументов.Хранимая процедура содержит динамический 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

Такой подход позволяет легко добавлять новые запросы на фильтрацию

...