How do I build a dynamic Where clause with Dapper when passing in a model
You can also use Dapper's SqlBuilder.
Note that you'll have to install the Dapper.SqlBuilder NuGet package since it doesn't come with Dapper's main distribution.
Here is an example:
[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);
}
You can find some examples here.
This should do the trick for you, clean and 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) OPTION(RECOMPILE)";
return conn.Query<PersonModel>(selectSql, new
{
model.FirstName,
model.Lastname,
model.City,
Id = model.Id == 0? (int?)null: (int?)model.Id
}).ToList();