web-dev-qa-db-fra.com

Comment créer une clause Where dynamique avec Dapper lors de la transmission d'un modèle

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.

19
Eldorian

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!

44
Void Ray

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();
13
JFM

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.

0
Felipe Spinelli
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();
}
0
FakeisMe