2009-10-08 6 views
-1

J'ai actuellement un contrôleur avec le ActionResultFetch lignes avant et après l'élément réel en utilisant LINQ

public ActionResult Details(string sku) 
    { 
     Product p = _productRepository.GetProduct(sku); 

     return View("Details", p); 
    } 

suivant, je voudrais développer la requête LINQ pour retourner le produit avant ainsi que le produit après la la vue. Donc, au lieu de retourner un produit, je voudrais maintenant retourner trois produits.

  1. produit Avant (null s'il n'y a pas de produit avant)
  2. Produit dont le SKU est connu
  3. produit After (null s'il n'y a pas de produit après)

Toute aide serait très apprécié.

Merci

Répondre

0

Changer la vue à un type dictionnaire, et retourner un dictionnaire avec les touches précédentes, Current, Next. Remplissez les valeurs de votre référentiel. Dans la vue, vérifiez que les valeurs du dictionnaire sont nulles et ayez un contrôle pour afficher le SKU (s'il affiche plus d'un élément de données). Edit: Le code pour utiliser LINQ pour obtenir les éléments du repo est dans une réponse différente. Je disais que vous feriez quelque chose comme ce qui suit pour les amener à la vue

et la vue aurais les suivantes

Inherits="System.Web.Mvc.ViewPage<System.Collections.Generic.Dictionary<string, string>>" 

<% if (Model.ContainsKey("Previous")) { %><%=Model["Previous"] %><% } %> 
+0

Pouvez-vous montrer un exemple de code? Cela serait utile. Merci. – Thomas

1

En utilisant une table que j'avais à portée de main (comme vous avez fourni aucun schéma), en utilisant 5 comme un espace réservé pour une variable réelle LINQPad:

var pabove = (from p in PolicyStatuses 
where p.PolicyStatusID >= 5 
orderby p.PolicyStatusID ascending 
select p).Take(2); 

var pbelow = (from p in PolicyStatuses 
where p.PolicyStatusID <= 5 
orderby p.PolicyStatusID descending 
select p).Take(2); 

pabove.Union(pbelow).Dump(); 

Cette saisira au-dessus et un en dessous. Notez cependant que le retour de null ne se produit pas ici quand vous ne trouvez pas une ligne au-dessus ou au-dessous, il exclut simplement de tels résultats. Si vous vous souciez vraiment, vous pouvez prendre le compte de pabove et pbelow pour détecter si un tel enregistrement a été trouvé.

Le résultat (évidemment à nouveau de mon schéma):

IOrderedQueryable<PolicyStatus> (3 items) 
PolicyStatusID Status RecordCreated 
4 
Unknown 
8/26/2007 11:06:11 PM 

5 
Expired 
8/26/2007 11:06:11 PM 

6 
Cancelled 
8/26/2007 11:06:11 PM 

Notez que 4, 5 et 6 ont été trouvés. Cela a un avantage sur le chargement de la table entière et la sélection des résultats près de celui que vous voulez. En utilisant Take (2), seulement 3 enregistrements doivent traverser le fil de votre serveur SQL vers votre serveur Web. Si votre table est suffisamment petite, il vous suffit d'interroger la table avec un tri et de filtrer ce dont vous avez besoin.

Voici le SQL produit par LINQ (certains champs omis):

SELECT [t2].[PolicyStatusID], [t2].[Status], [t2].[RecordCreated] 
FROM (
    SELECT TOP (2) [t0].[PolicyStatusID], [t0].[Status], [t0].[RecordCreated] 
    FROM [PolicyStatus] AS [t0] 
    WHERE [t0].[PolicyStatusID] >= @p0 
    ORDER BY [t0].[PolicyStatusID] 
    UNION 
    SELECT TOP (2) [t1].[PolicyStatusID], [t1].[Status], [t1].[RecordCreated] 
    FROM [PolicyStatus] AS [t1] 
    WHERE [t1].[PolicyStatusID] <= @p1 
    ORDER BY [t1].[PolicyStatusID] DESC 
    ) AS [t2] 
0

Vous devez définir une commande pour vos produits, avant de pouvoir déterminer quel produit est avant ou après un autre produit. Une fois que vous définissez une commande, vous pouvez faire quelque chose de similaire à ce que suggérait @Godeke.

La commande est entièrement à vous, mais devrait donner un sens à l'utilisateur. Commander par une colonne ID n'est probablement pas la bonne approche. La commande par nom/nom d'affichage, date d'ajout, prix le plus bas, etc. sera logique.

Mieux encore, permettre à l'utilisateur de définir la commande.

Questions connexes