传入模型时如何使用 Dapper 构建动态 Where 子句

新手上路,请多包涵

我有一个看起来像这样的示例模型:

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

我的问题是如何在我的 repo 方法中正确构建它?

原文由 Eldorian 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.4k
2 个回答

你也可以使用 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);
    }

您可以 在此处 找到一些示例。

原文由 Void Ray 发布,翻译遵循 CC BY-SA 4.0 许可协议

如果您想尝试另一种选择, DapperQueryBuilder 可能更容易使用:

 var query = cn.QueryBuilder($@"
    SELECT *
    FROM PersonTable
   /**where**/
");

if (model.Id > 0)
    query.Where($"Id = {model.Id}");

if (!string.IsNullOrEmpty(model.FirstName))
    query.Where($"FirstName = {model.FirstName}");

if (!string.IsNullOrEmpty(model.Lastname))
    query.Where($"Lastname = {model.Lastname}");

if (!string.IsNullOrEmpty(model.City))
    query.Where($"City = {model.City}");

var results = query.Query<Person>();

Query<Person>() 将调用 Dapper 传递底层 SQL 和参数。

底层查询是完全参数化的 SQL

WHERE FirstName = @p0 AND LastName = @p1

或者,更简单:

 var query = cn.QueryBuilder($"SELECT * FROM PersonTable WHERE 1=1");

if (model.Id > 0)
    query += $"AND Id = {model.Id}";

if (!string.IsNullOrEmpty(model.FirstName))
    query += $"AND FirstName = {model.FirstName}";

if (!string.IsNullOrEmpty(model.Lastname))
    query += $"AND Lastname = {model.Lastname}";

if (!string.IsNullOrEmpty(model.City))
    query += $"AND City = {model.City}";

var results = query.Query<Person>();

免责声明:我是这个库的作者之一

原文由 drizin 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进