Wie filtert man in Dapper mit einer Sammlung mit mehreren Eigenschaften?

.net-core c# dapper

Frage

Ich bin Dapper etwas neu und versuche eine saubere Methode zu finden, einen Filterparameter an SQL Query für eine Sammlung mit mehr als einer Eigenschaft zu übergeben.

Meine Sammlung sieht so aus:

[{
    Prop1: 'A Value 1',
    Prop2: 'B Value 1'
},
{
    Prop1: 'A Value 2',
    Prop2: 'B Value 2'
}]

Was zu einer SQL-Abfrage führen sollte, die ungefähr so ​​aussieht:

select *
from SampleTable
where
([ColumnA]='A Value 1' and [ColumnB]='B Value 1')
or ([ColumnA]='A Value 2' and [ColumnB]='B Value 2')

Hinweis: Etwas wie das unten gezeigte funktioniert nicht, da die beiden Eigenschaften PropA und PropB zusammen gefiltert werden müssen.

string query = @"select *
                from SampleTable
                where [ColumnA] in (@PropA_Value)
                and [ColumnB] in (@PropB_Value)"

con.Query<T>(query, new{PropA_Value = PropA,PropB_Value = PropB}).AsList();

Beliebte Antwort

Sie können Filterzeichenfolgen dynamisch mithilfe der folgenden Hilfsklasse generieren:

public static class DapperHelper
    {
        private const string SingleTupleFormat = " [{0}] = '{1}' {2}";
        private const string AndString = "AND";
        private const string OrString = "OR";

        private static string ToSqlTuple(List<Dictionary<string, string>> filters) 
        {
             string filterParam = string.Empty;
             foreach (var filter in filters)
             {
                 //Construct single tuple
                 string tuple = filter.ToList().Aggregate(string.Empty,
                 (current, pair) => current + String.Format(SingleTupleFormat, pair.Key, pair.Value, AndString));

                 //Concatenate tuples by OR, string.Format to combine the different filters
                 filterParam += string.Format(" ({0}) {1}", tuple.TrimEnd(AndString), OrString);
             }
             return filterParam.TrimEnd(OrString);
         }

        public static string TrimEnd(this string source, string value)
        {
            if (!source.EndsWith(value))
                return source;

            return source.Remove(source.LastIndexOf(value));
        }
    }

Verwendung:

string query = @"select *
                from SampleTable
                where @where";

List<Dictionary<string, string>> filters = new List<Dictionary<string, string>>() {
                new Dictionary<string, string>(){{"ColumnA", "A Value 1"},{"ColumnB", "A Value 2"}},
                new Dictionary<string, string>(){{"ColumnA", "B Value 1"},{"ColumnB", "B Value 2"}}
            };

var tuple = DapperHelper.ToSqlTuple(filters);
query = query.Replace("@where", string.IsNullOrEmpty(tuple) ? "1=1" : tuple); //Use 1=1 if tuple is empty or null

var data = con.Query<T>(query).AsList();

Die Abfragezeichenfolge sieht folgendermaßen aus:

select *
from SampleTable
where  ( [ColumnA] = 'A Value 1' AND [ColumnB] = 'A Value 2' ) 
    OR ( [ColumnA] = 'B Value 1' AND [ColumnB] = 'B Value 2' )


Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum