2009-08-20 14 views
2

Je souhaite exécuter une requête LINQ avec une clause dynamic where en fonction du nombre d'options saisies par l'utilisateur pour ses critères.C# Clause WHERE dynamique dans une requête LINQ to SQL

Est-ce possible?

J'ai posté un code ci-dessous sur la façon dont je voudrais que cela fonctionne.

Quelqu'un a-t-il des suggestions?

P.S. J'ai essayé d'utiliser la méthode .Contains (générant un WHERE IN sur SQL, cependant le nombre de paramètres était supérieur au seuil 2100 et provoquait l'erreur "LINQ Le flux du protocole d'appel de procédure distante (RPC) du flux de données tabulaire entrant (TDS) est incorrect . ont été fournis dans cette requête RPC Trop de paramètres. Le maximum est de 2100" .

 

private struct ProductStruct 
     { 
      public long ProductID; 
     } 

     private struct FilterStruct 
     { 
      public long ProductTypeFieldID; 
      public long ValueNumber; 
     } 

List filterList = new List(); 
filterList.Add(new FilterStruct { ProductTypeFieldID = 3, ValueNumber = 195 }); 
filterList.Add(new FilterStruct { ProductTypeFieldID = 8, ValueNumber = 55 }); 

List productList = new List(); 

productList = (from pfv in dC.ProductFieldValues 
          where 
           foreach (FilterStruct filter in filterList) 
           { 
            pfv.ProductTypeFieldID == filter.ProductTypeFieldID 
            && pfv.ValueNumber == filter.ValueNumber 
           } 
          select new ProductStruct 
          { 
           ProductID = pfv.ProductID 
          }).ToList(); 
 

EDIT

cela semble que cela pourrait être un travail à portée de main, mais ne marche pas avec une dynamique où en?

 


private void Option2() 
     { 
      try 
      { 
       LinqDataDataContext dataConnection = new LinqDataDataContext(ConnectionString); 

       List filterList = new List(); 
        filterList.Add(new FilterStruct { ProductTypeFieldID = 3, ValueNumber = 195 }); 
        filterList.Add(new FilterStruct { ProductTypeFieldID = 8, ValueNumber = 55 }); 

       string whereClause = null; 
       foreach (FilterStruct filter in filterList) 
       { 
        if (whereClause != null) 
         whereClause += "AND "; 

        whereClause += string.Format("ProductID IN (SELECT ProductID FROM ProductFieldValue WHERE ProductTypeFieldID = {0} AND ValueNumber = {1})", filter.ProductTypeFieldID, filter.ValueNumber); 

       } 


       List productList = new List(); 
        productList = (from pfv in dataConnection.ProductFieldValues.Where(whereClause) 
            select new ProductStruct 
              { 
              ProductID = pfv.ProductID 
              }).ToList(); 

      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.ToString()); 
      } 

     } 


thanks in advance 

Répondre

4

De la réponse acceptée ici: How do I build up LINQ dynamically

Cela fonctionne bien pour les classes .AsQueryable(), mais les classes .Enumerable() peut être utilisé si vous utilisez "comme IQueryable()"

linq using string as where statement http://www.scottgu.com/blogposts/dynquery/step2.png

+0

Je pense que l'idée d'utiliser Dynamic LINQ et de construire la clause where en tant que chaîne a du mérite. – tvanfosson

+0

Vous pourriez vouloir poster un résumé ici, ainsi votre réponse se tient toute seule. – tvanfosson

0

Vous pouvez utiliser une clause JOIN:

from pfv in dC.ProductFieldValues 
join filter in filterList on (
    pfv.ProductTypeFieldID == filter.ProductTypeFieldID 
    && pfv.ValueNumber == filter.ValueNumber 
) 
select new ProductStruct       
{        
    ProductID = pfv.ProductID       
} 
+0

Je pense que cela ne fonctionnerait que si la demande initiale était materializ ed et vous avez fait la jointure avec LINQ to Objects. Je suppose que l'OP voudrait que le filtrage soit fait sur le serveur SQL, sinon il pourrait juste les parcourir et supprimer ceux qu'il ne veut pas. – tvanfosson

0

Voici un exemple simple en utilisant IQueryable en VB.

Private Function GetZeroScoreWhere(ByVal qry As IQueryable(Of ScoreTest), ByVal score As ScoreTest) As IQueryable(Of ScoreTest) 
    If score.CallType = ScoreTest.CallTypeEnum.XXX Then 
     Return qry.Where(Function(c) c.AvgScore.Value = 0 Or c.Zero.Trim <> String.Empty) 
    End If 

    Return qry.Where(Function(c) c.ValidScore.Value = 0) 
End Function 

Le même code en C#:

private IQueryable<ScoreTest> GetZeroScoreWhere(IQueryable<ScoreTest> qry, ScoreTest score) 
{ 
    if(score.CallType == ScoreTest.CallTypeEnum.XXX) 
    { 
     Return qry.Where(c => c.AvgScore.Value == 0 || c.Zero.Trim != String.Empty) 
    } 

    Return qry.Where(c => c.ValidScore.Value == 0)  
} 
Questions connexes