次のようなモデルの例があります。
public class PersonModel
{
public int Id {get; set;}
public string FirstName {get; set;}
public string Lastname {get; set;}
public string City {get; set;}
}
リポジトリで、モデルを渡す検索メソッドを作成しますが、すべてのフィールドが常に入力されるわけではありません。モデルのフィールドにデータが入力されているかどうかに基づいて、WHEREとANDを作成したい。フィールドにデータが入力されていない場合、WHERE句を作成したくありません。
たとえば、FirstName = "Bob"およびCity = "Boston"を渡すと、検索は次のようになります。
SELECT * FROM PersonTable WHERE FirstName = @firstName AND City = @city
IdまたはLastNameを渡さなかったため、クエリに追加したくありません。 City = "Boston"を渡すと、次のようになります。
SELECT * FROM PersonTable WHERE City = @city
私のレポ方法は次のようになります
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();
}
私の質問は、レポ方法でこれをどのように適切に構築するのですか?
Dapperの SqlBuilder を使用することもできます。
Dapper.SqlBuilder NuGetパッケージはDapperのメインディストリビューションに付属していないため、インストールする必要があることに注意してください。
以下に例を示します。
[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);
}
いくつかの例を見つけることができます こちら 。
これは、きれいで簡単なトリックを実行するはずです:
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();
ExpressionExtensionSQL ライブラリを使用できます。このライブラリは、ラムダ式をwhere句に変換し、dapperおよび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();
}