2016-09-29 43 views
9

路過時,我有一個例子模型,看起來像這樣:如何建立一個動態凡與精緻小巧的第一個型號

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子句。

例如 - 如果我通過在名字=「鮑勃」和城市=「波士頓」,那麼我想我的搜索看起來像這樣:

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

您還可以使用小巧精緻的SqlBuilder

下面是一個例子:

[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

這應該爲你做的伎倆,乾淨和簡單:

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