C# – Hinzufügen dynamischer Parameter mit Dapper

C# – Hinzufügen dynamischer Parameter mit Dapper

Die einfachste Möglichkeit, dynamische Parameter mit Dapper hinzuzufügen, besteht darin, Dictionary:

zu übergeben
//Built dynamically somewhere
var query = "SELECT * FROM Movies WHERE Name=@Name";
var parameters = new Dictionary<string, object>()
{
	["Name"] = "The Matrix"
};

//Executing the query with dynamic parameters
using (var con = new SqlConnection(connectionString))
{
	var results = con.Query<Movie>(query, parameters);
	return results;
}
Code language: C# (cs)

Sie können auch dynamische Parameter hinzufügen, indem Sie die DynamicParameters-Klasse verwenden. Sie können den Ansatz verwenden, der im gegebenen Szenario am einfachsten ist. In diesem Artikel zeige ich Beispiele für das Hinzufügen dynamischer Parameter in verschiedenen Szenarien.

Dynamische Parameter einzeln hinzufügen

Sie können einzelne dynamische Parameter einzeln hinzufügen, indem Sie DynamicParameter.Add() verwenden.

//Built dynamically somewhere
var query = "SELECT * FROM Movies WHERE Id=@Id";
var paramName = "@Id"; //works without the @ too
var paramValue = 3;

//Dynamic parameters added individually
using (var con = new SqlConnection(connectionString))
{
	var dynamicParameters = new DynamicParameters();
	dynamicParameters.Add(paramName, paramValue);

	var results = con.Query<Movie>(query, dynamicParameters);
	return results;
}
Code language: C# (cs)

Als absolutes Minimum müssen Sie den Namen und den Wert hinzufügen. Add() hat weitere optionale Parameter. Dies ist vor allem dann nützlich, wenn Sie zusätzliche Informationen zu den Parametern hinzufügen.

Bekannte Parameter und dynamische Parameter hinzufügen

Wenn Sie im Voraus wissen, welche Parameter Sie verwenden, können Sie Dapper einen param übergeben Objekt mit Eigenschaften für jeden Parameter. Wenn Sie auch dynamische Parameter hinzufügen müssen, fügen Sie sie mit der DynamicParameters-Klasse hinzu, und fügen Sie den param hinzu Objekt mit der Methode AddDynamicParams(). Hier ist ein Beispiel:

//Built dynamically somewhere
var query = "SELECT * FROM Movies WHERE Name=@Name AND YearOfRelease=@Year";
var parameters = new Dictionary<string, object>()
{
	["Year"] = 1999
};

//Using hardcoded (known) parameters  + dynamic parameters
using (var con = new SqlConnection(connectionString))
{
	var dynamicParameters = new DynamicParameters(parameters);

	dynamicParameters.AddDynamicParams(new { name = "The Matrix" });
		
	var results = con.Query<Movie>(query, dynamicParameters);
	return results;
}
Code language: C# (cs)

Wie gezeigt, können Sie das DynamicParameters-Objekt mit Dictionary initialisieren und dann alle zusätzlichen Parameter hinzufügen, die Sie benötigen.

Erhalten eines gespeicherten Prozessausgabeparameters

Sie können die DynamicParameters-Klasse verwenden, um einen gespeicherten proc-Ausgabeparameter abzurufen. Stellen Sie beim Hinzufügen dieses Parameters sicher, dass Sie den DbType festlegen und ParameterDirection.Output verwenden. Nachdem Sie die Abfrage ausgeführt haben, können Sie den Ausgabeparameterwert aus dem DynamicParameters-Objekt abrufen. Hier ist ein Beispiel für das Hinzufügen bekannter Eingabeparameter (mit AddDynamicParams()) und eines Ausgabeparameters:

var year = 2022;

using (var con = new SqlConnection(connectionString))
{
	var dynamicParameters = new DynamicParameters();
	dynamicParameters.AddDynamicParams(new { year });
	dynamicParameters.Add("count", DbType.Int32, direction: ParameterDirection.Output);

	var results = con.Query<Movie>("spGetMoviesForYear", dynamicParameters, commandType: CommandType.StoredProcedure);

	var count = dynamicParameters.Get<int>("count");
	Console.WriteLine($"Got {count} records");

	return results;
}
Code language: C# (cs)

Müssen Sie den DbType-Parameter festlegen? Ja. Andernfalls erhält es möglicherweise den falschen Wert. Wenn ich beispielsweise den DbType-Parameter nicht auf DbType.Int32 setze, kommt der Ausgabeparameter als 2 statt 65 zurück. Setzen Sie immer den DbType für Ausgabeparameter.

WHERE LIKE mit einem dynamischen Parameter

Wenn Sie Abfragen/Parameter dynamisch erstellen, müssen Sie häufig Teilübereinstimmungen mit dem LIKE-Operator unterstützen. Damit LIKE mit einem Parameter funktioniert, fügen Sie % zum Parameterwert hinzu:

//Built dynamically somewhere
var movieNameLike = "Matrix";
var query = "SELECT * FROM Movies WHERE Name LIKE @Name";
var parameters = new Dictionary<string, object>()
{
	["Name"] = $"%{movieNameLike}%"
};

//Using the dynamic parameters like usual
using (var con = new SqlConnection(connectionString))
{
	var results = con.Query<Movie>(query, parameters);
	return results;
}
Code language: C# (cs)

Hinweis:Das Gleiche gilt für bekannte Parameter, die Sie mit LIKE verwenden. Dies ist nicht spezifisch für dynamische Parameter.

WHERE IN mit einem dynamischen Parameter

Sie können WHERE IN mit dynamischen Parametern verwenden. Verwenden Sie die von Dapper geforderte IN-Syntax (ohne umgebende Klammern):

//Built dynamically somewhere
var query = "SELECT * FROM Movies WHERE Id IN @Ids";
var parameters = new Dictionary<string, object>()
{
	["Ids"] = new List<int>()
	{
		17, 18, 19
	}
};

//Using the dynamic parameters like usual
using (var con = new SqlConnection(connectionString))
{
	var results = con.Query<Movie>(query, parameters);
	return results;
}
Code language: C# (cs)

Ergebnisse einem dynamischen Objekt zuordnen

Wenn Sie echte Ad-hoc-Abfragen ausführen, haben Sie möglicherweise keine Klasse, der Sie die Ergebnisse zuordnen können, und möchten möglicherweise keine. Verwenden Sie in diesem Fall, anstatt einen zuzuordnenden Typ anzugeben (z. B. Query()), die nicht generische Query()-Methode, die IEnumerable:

zurückgibt
using (var con = new SqlConnection(connectionString))
{
	IEnumerable<dynamic> results = con.Query(query, parameters);
	return results;
}
Code language: C# (cs)