Domanda

Qual è il modo migliore per assemblare una dinamica clausola WHERE una dichiarazione LINQ?

Ho diverse decine di caselle di controllo su un form e sto passandoli indietro come:. Dictionary > (Dictionary >) per la mia query LINQ

public IOrderedQueryable<ProductDetail> GetProductList(string productGroupName, string productTypeName, Dictionary<string,List<string>> filterDictionary)
{
    var q = from c in db.ProductDetail
            where c.ProductGroupName == productGroupName && c.ProductTypeName == productTypeName
            // insert dynamic filter here
            orderby c.ProductTypeName
            select c;
    return q;
}
È stato utile?

Soluzione

alt text
(fonte: scottgu.com )

Hai bisogno di qualcosa di simile? Utilizzare il Query dinamica Biblioteca Linq (download include esempi).

Scopri di ScottGu blog per ulteriori esempi.

Altri suggerimenti

È inoltre possibile utilizzare il PredicateBuilder da LinqKit a catena molteplici espressioni lambda typesafe utilizzando Or o E.

http://www.albahari.com/nutshell/predicatebuilder.aspx

Ho scenario simile in cui ho bisogno di aggiungere filtri basati sull'input dell'utente e catena in cui clausola.

Ecco il codice di esempio.

var votes = db.Votes.Where(r => r.SurveyID == surveyId);
if (fromDate != null)
{
    votes = votes.Where(r => r.VoteDate.Value >= fromDate);
}
if (toDate != null)
{
    votes = votes.Where(r => r.VoteDate.Value <= toDate);
}
votes = votes.Take(LimitRows).OrderByDescending(r => r.VoteDate);

Un approccio semplice può essere se le colonne sono di semplice tipo come String

public static IEnumerable<MyObject> WhereQuery(IEnumerable<MyObject> source, string columnName, string propertyValue)
{
   return source.Where(m => { return m.GetType().GetProperty(columnName).GetValue(m, null).ToString().StartsWith(propertyValue); });
}

mi si avvicinò con una soluzione che anche io posso capire ... utilizzando il metodo 'Contiene' è possibile concatenare quanti Dov'è che vuoi. Se il WHERE è una stringa vuota, è ignorato (o valutato come un Seleziona tutto). Qui è il mio esempio di unire 2 tavoli in LINQ, applicando multipli in cui le clausole e la compilazione di una classe di modello da restituire alla vista. (Questo è un Seleziona tutto).

public ActionResult Index()
    {
        string AssetGroupCode = "";
        string StatusCode = "";
        string SearchString = "";

        var mdl = from a in _db.Assets
                  join t in _db.Tags on a.ASSETID equals t.ASSETID
                  where a.ASSETGROUPCODE.Contains(AssetGroupCode)
                  && a.STATUSCODE.Contains(StatusCode)
                  && (
                  a.PO.Contains(SearchString)
                  || a.MODEL.Contains(SearchString)
                  || a.USERNAME.Contains(SearchString)
                  || a.LOCATION.Contains(SearchString)
                  || t.TAGNUMBER.Contains(SearchString)
                  || t.SERIALNUMBER.Contains(SearchString)
                  )
                  select new AssetListView
                  {
                      AssetId = a.ASSETID,
                      TagId = t.TAGID,
                      PO = a.PO,
                      Model = a.MODEL,
                      UserName = a.USERNAME,
                      Location = a.LOCATION,
                      Tag = t.TAGNUMBER,
                      SerialNum = t.SERIALNUMBER
                  };


        return View(mdl);
    }

ho avuto stessa domanda ( filtro definito utente per LINQ ), e @tvanfosson mi ha parlato di dinamica Linq ( http://code.msdn.microsoft.com/csharpsamples ) .

È possibile utilizzare il metodo di estensione Qualsiasi (). Quanto segue sembra funzionare per me.

XStreamingElement root = new XStreamingElement("Results",
                from el in StreamProductItem(file)
                where fieldsToSearch.Any(s => el.Element(s) != null && el.Element(s).Value.Contains(searchTerm))
                select fieldsToReturn.Select(r => (r == "product") ? el : el.Element(r))
            );
            Console.WriteLine(root.ToString());

Dove 'fieldsToSearch' e 'fieldsToReturn' sono entrambi gli oggetti List.

Questo progetto su CodePlex avere quello che vuoi.

System.Linq.Dynamic - http://dynamiclinq.codeplex.com/

  

Descrizione del progetto

     

Estende System.Linq.Dynamic per supportare l'esecuzione di espressioni Lambda definiti in una stringa contro Entity Framework o di qualsiasi provider che supporti IQueryable.

Come è un'estensione del codice sorgente si può trovare su Blog di Scott Guthrie vi permetterà di fare cose come questa:

entrare descrizione dell'immagine qui

E cose come questa:

entrare descrizione dell'immagine qui

Questa è la soluzione mi è venuta se qualcuno è interessato.

https: // kellyschronicles. wordpress.com/2017/12/16/dynamic-predicate-for-a-linq-query/

Per prima cosa identifichiamo il tipo di elemento singolo abbiamo bisogno di usare (Of Trow Come DataRow) e quindi identificare la “fonte” stiamo usando e legare l'identificatore a quella sorgente ((fonte come TypedTableBase (Of Trow)). Poi abbiamo deve specificare il predicato, o la clausola WHERE che sta per essere passato (predicato come func (di Trow, booleano)), che sia restituita come vera o falsa. Poi ci identifichiamo come vogliamo le informazioni restituite ordinato (OrderByField As String ). la nostra funzione sarà poi restituire un EnumerableRowCollection (Of Trow), la nostra collezione di DataRow che hanno soddisfatto le condizioni del nostro predicato (EnumerableRowCollection (Of Trow)). Questo è un esempio di base. Naturalmente è necessario assicurarsi che il proprio doesn campo ordine 't contengono valori nulli, o hanno gestito quella situazione correttamente e assicurarsi che le nomi delle colonne (se si utilizza un dataSource fortemente tipizzato non importa questo, sarà rinominare le colonne per voi) sono di serie.

Sembra molto più semplice e più semplice da usare l'operatore ternario di decidere in modo dinamico se una condizione è incluso

Lista Lista prodotti = new List ();

        productList =
                db.ProductDetail.Where(p => p.ProductDetailID > 0 //Example prop
                && (String.IsNullOrEmpty(iproductGroupName) ? (true):(p.iproductGroupName.Equals(iproductGroupName)) ) //use ternary operator to make the condition dynamic
                && (ID == 0 ? (true) : (p.ID == IDParam))
                ).ToList();
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top