Dapper-QueryBuilder
1.0.0
See the version list below for details.
dotnet add package Dapper-QueryBuilder --version 1.0.0
NuGet\Install-Package Dapper-QueryBuilder -Version 1.0.0
<PackageReference Include="Dapper-QueryBuilder" Version="1.0.0" />
paket add Dapper-QueryBuilder --version 1.0.0
#r "nuget: Dapper-QueryBuilder, 1.0.0"
// Install Dapper-QueryBuilder as a Cake Addin #addin nuget:?package=Dapper-QueryBuilder&version=1.0.0 // Install Dapper-QueryBuilder as a Cake Tool #tool nuget:?package=Dapper-QueryBuilder&version=1.0.0
Dapper Query Builder
Dapper Query Builder using Fluent API and String Interpolation
We all love Dapper and how Dapper is a minimalist library.
This library is a wrapper around Dapper mostly for helping building dynamic SQL queries and commands. It's based on a few fundamentals:
1. String interpolation instead of manually using DynamicParameters
By using interpolated strings we can pass parameters to Dapper without having to worry about creating and managing DynamicParameters manually. You can build your queries with interpolated strings, and this library will automatically "parametrize" your values.
(If you just passed an interpolated string to Dapper, you would have to manually sanitize your inputs against SQL-injection attacks, and on top of that your queries wouldn't benefit from cached execution plan).
So instead of writing like this:
sql += " AND Name LIKE @productName";
dynamicParams.Add("productName", productName);
var products = cn.Query<Product>(sql, dynamicParams);
Or like this:
sql += $" AND Name LIKE {productName.Replace("'", "''")}";
var products = cn.Query<Product>(sql); // pray that you sanitized correctly against sql-injection
You can just write like this:
cmd.Append($" AND Name LIKE {productName}");
// query and parameters are wrapped inside CommandBuilder or QueryBuilder and passed automatically to Dapper
var products = cmd.Query<Product>();
2. Combining Filters
Like other QueryBuilders you can create your filters dynamically (with interpolated strings, which is our mojo and charm), and combine AND/OR filters. Different from other builders, we don't try to reinvent SQL syntax or create a limited abstraction over SQL language, which is powerful, comprehensive, and vendor-specific.
You can still write your queries on your own, and yet benefit from string interpolation and from dynamically building a list of parametrized filters.
var q = cn.QueryBuilder(@"SELECT ProductId, Name, ListPrice, Weight
FROM [Production].[Product]
/**where**/
ORDER BY ProductId
");
q.Where(new Filters()
{
new Filter($"[ListPrice] >= {minPrice}"),
new Filter($"[ListPrice] <= {maxPrice}")
});
q.Where(new Filters(Filters.FiltersType.OR)
{
new Filter($"[Weight] <= {maxWeight}"),
new Filter($"[Name] LIKE {search}")
});
// Query() will automatically build your SQL query, and will replace your /**where**/ (if any filter was added)
// it will also pass an underlying DynamicParameters object, with all parameters you passed using string interpolation
var products = q.Query<Product>();
3. Fluent API (Chained-methods)
For those who like method-chaining guidance, there's a Fluent API which allows you to build queries step-by-step mimicking dynamic SQL concatenation.
var q = cn.QueryBuilder()
.Select("ProductId") // you could also use nameof(Product.ProductId) to use "find references" and refactor(rename)
.Select("Name")
.Select("ListPrice")
.Select("Weight")
.From("[Production].[Product]")
.Where($"[ListPrice] <= {maxPrice}")
.Where($"[Weight] <= {maxWeight}")
.Where($"[Name] LIKE {search}")
.OrderBy("ProductId");
var products = q.Query<Product>();
You would get this query:
SELECT ProductId, Name, ListPrice, Weight
FROM [Production].[Product]
WHERE [ListPrice] <= @p0 AND [Weight] <= @p1 AND [Name] LIKE @p2
ORDER BY ProductId
Documentation / More Examples
Manual Query (Templating) With Type-Safe Dynamic Filters:
You can still write your queries on your own, and yet benefit from string interpolation and from dynamically building a list of filters.
All filters added to QueryBuilder are automatically added to the underlying DynamicParameters object,
and when you invoke Query we build the filter statements and replace the /**where**/
keyword which you used in your templated-query.
int maxPrice = 1000;
int maxWeight = 15;
string search = "%Mountain%";
var cn = new SqlConnection(connectionString);
// You can build the query manually and just use QueryBuilder to replace "where" filters (if any)
var q = cn.QueryBuilder(@"SELECT ProductId, Name, ListPrice, Weight
FROM [Production].[Product]
/**where**/
ORDER BY ProductId
");
// You just pass the parameters as if it was an interpolated string,
// and QueryBuilder will automatically convert them to Dapper parameters (injection-safe)
q.Where($"[ListPrice] <= {maxPrice}");
q.Where($"[Weight] <= {maxWeight}");
q.Where($"[Name] LIKE {search}");
// Query() will automatically build your query and replace your /**where**/ (if any filter was added)
var products = q.Query<Product>();
You would get this query:
SELECT ProductId, Name, ListPrice, Weight
FROM [Production].[Product]
WHERE [ListPrice] <= @p0 AND [Weight] <= @p1 AND [Name] LIKE @p2
ORDER BY ProductId
Passing IN (lists) and building joins dynamically using Fluent API:
var categories = new string[] { "Components", "Clothing", "Acessories" };
var q = cn.QueryBuilder()
.SelectDistinct("c.[Name] as [Category], sc.[Name] as [Subcategory], p.[Name], p.[ProductNumber]")
.From("[Production].[Product] p")
.From("INNER JOIN [Production].[ProductSubcategory] sc ON p.[ProductSubcategoryID]=sc.[ProductSubcategoryID]")
.From("INNER JOIN [Production].[ProductCategory] c ON sc.[ProductCategoryID]=c.[ProductCategoryID]")
.Where($"c.[Name] IN {categories}");
There are also chained-methods for adding GROUP BY, HAVING, ORDER BY, and paging (OFFSET x ROWS / FETCH NEXT x ROWS ONLY).
Invoking Stored Procedures:
// This is basically Dapper, but with a FluentAPI where you can append parameters dynamically.
var q = cn.CommandBuilder($"[HumanResources].[uspUpdateEmployeePersonalInfo]")
.AddParameter("ReturnValue", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue)
.AddParameter("ErrorLogID", dbType: DbType.Int32, direction: ParameterDirection.Output)
.AddParameter("BusinessEntityID", businessEntityID)
.AddParameter("NationalIDNumber", nationalIDNumber)
.AddParameter("BirthDate", birthDate)
.AddParameter("MaritalStatus", maritalStatus)
.AddParameter("Gender", gender);
int affected = q.Execute(commandType: CommandType.StoredProcedure);
int returnValue = q.Parameters.Get<int>("ReturnValue");
Using Type-Safe Filters without QueryBuilder If for any reason you don't want to use our QueryBuilder, you can still use type-safe dynamic filters:
Dapper.DynamicParameters parms = new Dapper.DynamicParameters();
var filters = new Filters(Filters.FiltersType.AND);
filters.Add(new Filters()
{
new Filter($"[ListPrice] >= {minPrice}"),
new Filter($"[ListPrice] <= {maxPrice}")
});
filters.Add(new Filters(Filters.FiltersType.OR)
{
new Filter($"[Weight] <= {maxWeight}"),
new Filter($"[Name] LIKE {search}")
});
string where = filters.BuildFilters(parms);
// "WHERE ([ListPrice] >= @p0 AND [ListPrice] <= @p1) AND ([Weight] <= @p2 OR [Name] LIKE @p3)"
// parms contains @p0 as minPrice, @p1 as maxPrice, etc..
License
MIT License
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 is compatible. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.7.2
- Dapper (>= 2.0.35)
- Microsoft.CSharp (>= 4.7.0)
-
.NETStandard 2.0
- Dapper (>= 2.0.35)
- Microsoft.CSharp (>= 4.7.0)
NuGet packages (7)
Showing the top 5 NuGet packages that depend on Dapper-QueryBuilder:
Package | Downloads |
---|---|
DapperChunk
感谢开源库 Dapper DapperQueryBuilder 1.Dapper Chunks 用于大数据处理 2.Dapper Sqlbuilder sql 构建器,仿照 开源库 FluentQueryBuilder 构建.(目前实现 mysql,mssql,sqlite), FluentQueryExtensions.Register注册 数据库类型与构建器的映射关系 |
|
ViraVenda.Core
Biblioteca core do aplicativo Vira Venda |
|
Codibre.GrpcSqlProxy.Client
Package Description |
|
Harbin.DataAccess
Data Access library based on Dapper, Dapper.FastCRUD, and DapperQueryBuilder. Implement Repositories (Generic Repository Pattern) and helps to manage connections to distributed databases and/or read-replicas. |
|
Harbin.DataAccess.DapperFastCRUD
Data Access library based on Dapper, Dapper.FastCRUD, and DapperQueryBuilder. Implement Repositories (Generic Repository Pattern) and helps to manage connections to distributed databases and/or read-replicas. |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated | |
---|---|---|---|
2.0.0 | 32,113 | 3/17/2024 | |
2.0.0-beta2 | 106 | 3/14/2024 | |
2.0.0-beta1 | 1,498 | 7/10/2023 | |
1.2.9 | 274,240 | 1/7/2023 | |
1.2.8 | 410 | 1/7/2023 | |
1.2.7 | 114,819 | 7/31/2022 | |
1.2.6 | 1,052 | 7/28/2022 | |
1.2.5 | 73,119 | 5/9/2022 | |
1.2.4 | 15,867 | 3/6/2022 | |
1.2.3 | 4,013 | 2/22/2022 | |
1.2.2 | 4,268 | 2/13/2022 | |
1.2.1 | 539 | 2/13/2022 | |
1.2.0 | 91,287 | 11/4/2021 | |
1.1.1 | 6,588 | 10/24/2021 | |
1.1.0 | 159,089 | 5/1/2021 | |
1.0.9 | 4,028 | 4/20/2021 | |
1.0.8 | 7,619 | 3/30/2021 | |
1.0.7 | 52,332 | 3/6/2021 | |
1.0.6 | 4,508 | 2/9/2021 | |
1.0.5 | 14,898 | 12/25/2020 | |
1.0.4 | 39,610 | 8/18/2020 | |
1.0.3 | 832 | 8/6/2020 | |
1.0.2 | 623 | 8/5/2020 | |
1.0.1 | 581 | 8/3/2020 | |
1.0.0 | 1,916 | 8/2/2020 |