J'ai un exemple de modèle qui ressemble à ceci:
public class PersonModel
{
public int Id {get; set;}
public string FirstName {get; set;}
public string Lastname {get; set;}
public string City {get; set;}
}
Dans mon référentiel, je souhaite créer une méthode de recherche dans laquelle je passe dans mon modèle - mais tous les champs ne seront pas toujours renseignés. Je veux créer un WHERE et AND basé sur si un champ du modèle est rempli ou non. Si le champ n'est pas renseigné, je ne souhaite pas créer de clause WHERE pour celui-ci.
Par exemple, si je passe dans FirstName = "Bob" et City = "Boston", je souhaite que ma recherche ressemble à ceci:
SELECT * FROM PersonTable WHERE FirstName = @firstName AND City = @city
Depuis que je n'ai pas passé id ou LastName je ne veux pas les ajouter à la requête. Si je passe juste dans City = "Boston" alors je veux que ça ressemble à ceci:
SELECT * FROM PersonTable WHERE City = @city
Ma méthode de repo ressemblerait à quelque chose comme ça
using Dapper;
public List<PersonModel> Search(PersonModel model)
{
//db = DbConnection connection
var selectSql = "SELECT * FROM PersonTable "; //build out where clause somehow
return db.Query<PersonModel>(selectSql).ToList();
}
Ma question est de savoir comment je construirais cela correctement dans ma méthode de pension.
Vous pouvez également utiliser Dapper's SqlBuilder
Voici un exemple:
[Test]
public void Test()
{
var model = new PersonModel {FirstName = "Bar", City = "New York"};
var builder = new SqlBuilder();
//note the 'where' in-line comment is required, it is a replacement token
var selector = builder.AddTemplate("select * from table /**where**/");
if (model.Id > 0)
builder.Where("Id = @Id", new { model.Id });
if (!string.IsNullOrEmpty(model.FirstName))
builder.Where("FirstName = @FirstName", new { model.FirstName });
if (!string.IsNullOrEmpty(model.Lastname))
builder.Where("Lastname = @Lastname", new { model.Lastname });
if (!string.IsNullOrEmpty(model.City))
builder.Where("City = @City", new { model.City });
Assert.That(selector.RawSql, Is.EqualTo("select * from table WHERE FirstName = @FirstName AND City = @City\n"));
//var rows = sqlConnection.Query(selector.RawSql, selector.Parameters);
}
Vous pouvez trouver quelques exemples ici!
Cela devrait faire l'affaire pour vous, propre et simple:
var selectSql = "SELECT * FROM PersonTable WHERE (@FirstName IS NULL OR FirstName = @FirstName) AND (@LastName IS NULL OR LastName = @LastName) AND (@City IS NULL OR City = @City) AND (@Id IS NULL OR Id = @Id)";
return conn.Query<PersonModel>(selectSql, new
{
model.FirstName,
model.Lastname,
model.City,
Id = model.Id == 0? (int?)null: (int?)model.Id
}).ToList();
Vous pouvez utiliser la bibliothèque ExpressionExtensionSQL . Cette bibliothèque convertit les expressions lambda en clauses where et peut être utilisée avec dapper et ADO.
bool isFirstWhereSet = false;
bool isCityWhereSet = false;
string sqlQuery = "SELECT * FROM PersonTable " ;
if (! String.IsNullOrEmpty(model.FirstName ))
{
sqlQuery =sqlQuery + "WHERE FirstName =@FirstName" ;
isFirstWhereSet = true;
}
if (! String.IsNullOrEmpty(model.City))
{
isCityWhereSet = true ;
if (! isFirstWhereSet )
sqlQuery = sqlQuery + " WHERE City = @city";
else
sqlQuery = sqlQuery + " AND City = @city";
}
if (isFirstWhereSet == true && isCityWhereSet == true )
return db.Query<PersonModel>(sqlQuery , new { FirstName = model.FirstName , City = mode.City}).ToList();
else if (isFirstWhereSet == true && isCityWhereSet == false)
return db.Query<PersonModel>(sqlQuery , new { FirstName = model.FirstName }).ToList();
else if (isFirstWhereSet == false && isCityWhereSet == true)
return db.Query<PersonModel>(sqlQuery , new { City= model.City}).ToList();
else
{
return db.Query<PersonModel>(sqlQuery).ToList();
}