2016-09-29 13 views
9

を渡すとき、私はこのようになりますモデル例Dapperのと句を持つダイナミックビルドしてください:私は私に渡した検索方法を作成したい私のリポジトリにどのように私はモデルで

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句を作成する必要はありません。例えば

- 私は姓=「ボブ」と市=「ボストン」を渡すならば、私は私の検索は、次のようになりたい:私はIDや姓Iドンに合格しなかったので

SELECT * FROM PersonTable WHERE FirstName = @firstName AND City = @city 

それらをクエリに追加する必要はありません。私はちょうど市=「ボストン」を渡す場合、私はそれが次のようになりたい:

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(); 
} 

のようになります。私の質問は、私はこれを構築する方法をあります私のレポ方法で正しく?

+0

条件付きでwhere句を追加できます。儀式? – Shyju

+0

私はそう仮定しています、はい。しかし、私はそれを行う方法のまともな例を探しています。 – Eldorian

答えて

24

は一例です。

[Test] 
    public void Test() 
    { 
     var model = new PersonModel {FirstName = "Bar", City = "New York"}; 

     var builder = new SqlBuilder(); 
     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); 
    } 

あなたがすることができますいくつかの例を見つけるhere!

+0

ああ、Dapperには新しいので、他のパッケージがあることに気付かなかった。これはまさに私がそれをするのに必要なものでした。ありがとう。 – Eldorian

0
bool isFirstWhereSet = false; 
bool isCityWhereSet = false; 
string sqlQuery = "SELECT * FROM PersonTable " ; 
if (! String.IsNullOrEmpty(model.FirstName)) 
{ 
sqlQuery =sqlQuery + "WHERE FirstName [email protected]" ; 
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

多くの*** if-else *** – Kiquenet

9

これは、クリーンでシンプルな、あなたのためのトリックを行う必要があります:あなたはまた、ここではDapperののSqlBuilder

を使用することができます

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(); 
+0

確かに良い解決策、これはそれを達成する方法です –

+1

これは、C#条件付きSQLを構築するよりもきれいです。 OPTION(RECOMPILE)を使用することを検討して、クエリの最適化が実際に提供されたパラメータを考慮できるようにします。 – bbsimonbb

+0

Dapper.SqlBuilderを使用することを選択しなかった場合、これを受け入れられた回答として選択しました。 – Eldorian