2011-03-27 2 views
0

Je développe une application Web conçue pour interroger une table de base de données volumineuse en fonction de la sélection de critères par les utilisateurs. Dans certains cas, ils peuvent connaître et entrer la clé primaire, d'autres fois ils peuvent vouloir voir des enregistrements de statut 'abc' créés dans les 7 derniers jours, ou des enregistrements créés par 'fred smith' où la description contient le mot 'proposition'. Le point est, il pourrait facilement être 10 - 20 différentes variables qu'ils pourraient spécifier, basé sur ce qu'ils recherchent.ASP.NET 2.0 C# DAL Paramètres de variables multiples

Il m'est assez facile de construire l'instruction sql et d'appliquer dynamiquement les paramètres dans le code derrière la page Web (aspx.cs). Cette approche fonctionne bien. Cependant, j'ai lu sur l'utilisation d'un DAL BLL & (ou même juste un DAL) mais tous les exemples que j'ai vus ont été triviaux sans paramètres par exemple getCategories() ou un seul paramètre par exemple getProductByID (Donc, ce que je voudrais savoir sur comment mieux transmettre ma liste variable de nombreux paramètres à la BLL/DAL sans avoir une méthode avec (par exemple) 20 paramètres (cela est réalisable mais semble très lourd, en particulier si un nouveau paramètre de sélection est ajouté).

Les autres idées que j'ai pensé sont

a) Construire un seul paramètre de chaîne qui peut être décodé dans la méthode, par exemple:
chaîne params = « DateField = créé; FromDate = 2011-03- 01; Status = abc "
BLL.getRecords (params);
(Workable, mais terrible et sujette à erreurs)

b) utiliser une structure ou une classe en tant que paramètre, par exemple
params.Status = "abc";
params.createdByUser = 23;

(Y at-il un problème avec le DAL ayant accès à ce struct/classe? J'ai lu que le DAL ne doit pas partager toutes les références avec les classes qui l'appelle?

Merci pour toutes suggestions quant à la façon vous mettre en œuvre ce scénario.

Répondre

0

dans mes projets, je crée la classe statique DataManager qui expose toutes les fonctions nécessaires à l'obtention des données, par exemple

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

Comme vous le voyez dans le DB, nous avons une seule procédure stockée GetActionHistoryList (pour ActionHistory données de table) avec de nombreux arguments différents. La procédure stockée contient un SQL dynamique, par ex.

`<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 = @[email protected]+' 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 

Cette approche permet d'ajouter facilement de nouvelles demandes de filtrage

+0

Merci Stas - Il me semble que vous avez adopté l'approche de passer tous les 20 (ou autant de) paramètres au code qui appelle votre procédure stockée, en utilisant null pour chaque paramètre qui n'est pas nécessaire. C'est globalement similaire à la façon dont je construis dynamiquement le sql dans le code de plus haut niveau. Cependant, j'essaye d'accomplir ceci en passant un seul paramètre de sélection. – David

0

Vous pouvez créer une interface ISearchOption qui fournit les options nécessaires à la DAL. Vous pouvez fournir des surcharges courantes à GetRecords(ISearchOption options) qui construisent une instance interne ISearchOption et la transmettent à la surcharge GetRecords().

Une autre option consisterait à utiliser LINQ-to-SQL. Vous pouvez ensuite exposer la table en tant que IQueryable directement. Le code client dispose alors d'une liberté totale pour filtrer la table selon les besoins.

Questions connexes