SQLDapper.Easy 1.0.7

There is a newer version of this package available.
See the version list below for details.
dotnet add package SQLDapper.Easy --version 1.0.7
                    
NuGet\Install-Package SQLDapper.Easy -Version 1.0.7
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SQLDapper.Easy" Version="1.0.7" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SQLDapper.Easy" Version="1.0.7" />
                    
Directory.Packages.props
<PackageReference Include="SQLDapper.Easy" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SQLDapper.Easy --version 1.0.7
                    
#r "nuget: SQLDapper.Easy, 1.0.7"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SQLDapper.Easy@1.0.7
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SQLDapper.Easy&version=1.0.7
                    
Install as a Cake Addin
#tool nuget:?package=SQLDapper.Easy&version=1.0.7
                    
Install as a Cake Tool

SQL Easy Dapper

A high-performance, feature-rich Dapper-based data access service implementation that provides an extensive set of database operations with support for transactions, bulk operations, and entity tracking. A powerful and flexible SQL query builder implementation that supports LINQ-style syntax for building complex SQL queries with joins, aggregations, and more.

Features

  • 🚀 High-performance database operations
  • 📦 Bulk insert operations
  • 🔄 Transaction management with savepoints
  • 🔍 Entity tracking capabilities
  • 🛠 Support for stored procedures and functions
  • 💾 Cached query generation
  • 🔒 Thread-safe implementation
  • 🎯 Async support
  • 📝 Attribute-based mapping
  • 💾 Support composite primary key
  • 🔍 LINQ-style query syntax
  • 🔄 Support for complex JOINs (INNER, LEFT, RIGHT, FULL)
  • 📊 Aggregation functions (SUM, AVG, MIN, MAX, COUNT)
  • 📝 GROUP BY and HAVING clauses
  • 🔄 APPLY operations (CROSS APPLY, OUTER APPLY)
  • 📋 Pagination support
  • 🔒 SQL injection prevention
  • 🎨 Expression tree parsing
  • 📝 Support Row_Number, Union, UnionAll, Except and Intersect

Complete Method Examples

Constructor and Basic Methods

// Initialize with connection string

using EasyDapper;
using EasyDapper.Attributes;
IDapperService dapperService = DapperServiceFactory.Create("Your Connection String");
or
IDapperService dapperService = DapperServiceFactory.Create("Your IDbConnection object");

Entity Class Example

[Table(tableName: "Product", schema: "dbo")]
public class Product
{
    [PrimaryKey]
    [Identity]
    public int Id { get; set; }
    
    [Column("ProductName")]
    [PrimaryKey]
    public string Name { get; set; }
    
    public decimal Price { get; set; }
    
    public DateTime CreatedAt { get; set; }
}

Transaction Management

// Begin Transaction
dapperService.BeginTransaction();

// Nested transactions with savepoints
dapperService.BeginTransaction(); // First level
dapperService.BeginTransaction(); // Creates SavePoint1
dapperService.BeginTransaction(); // Creates SavePoint2

// Commit Transaction
dapperService.CommitTransaction();

// Rollback Transaction
dapperService.RollbackTransaction();

// Check transaction count
dapperService.TransactionCount();

// Example of complete transaction flow
try
{
    dapperService.BeginTransaction();
    
    var customer = new Customer { Name = "John Doe" };
    dapperService.Insert(customer);
    
    var order = new Order { CustomerId = customer.Id };
    dapperService.Insert(order);
    
    dapperService.CommitTransaction();
}
catch
{
    dapperService.RollbackTransaction();
    throw;
}

Single Entity Operations

// Insert single entity
var product = new Product { Name = "Sample Product", Price = 99.99m };
dapperService.Insert(product); // product.Id will be populated if it's an identity column

// Async Insert
await dapperService.InsertAsync(product);

// Update single entity
product.Price = 89.99m;
dapperService.Update(product);

// Async Update
await dapperService.UpdateAsync(product);

// Delete single entity
dapperService.Delete(product);

// Async Delete
await dapperService.DeleteAsync(product);

// Get entity by ID
var retrievedProduct = dapperService.GetById<Product>(1);

// Async Get by ID
var retrievedProductAsync = await dapperService.GetByIdAsync<Product>(1);

// Get by composite primary key
var compositeEntity = new CompositeKeyEntity { Key1 = 1, Key2 = "A" };
var retrieved = dapperService.GetById(compositeEntity);

// Async Get by composite key
var retrievedAsync = await dapperService.GetByIdAsync(compositeEntity);

Bulk Operations

// Insert multiple entities
var products = new List<Product>
{
    new Product { Name = "Product 1", Price = 10.99m },
    new Product { Name = "Product 2", Price = 20.99m }
};
dapperService.InsertList(products, generateIdentities: true);

// Async Insert multiple entities with generate iodentity keys and set to identity property mapped
await dapperService.InsertListAsync(products, generateIdentities: true);

// Update multiple entities
products.ForEach(p => p.Price += 5.0m);
dapperService.UpdateList(products);

// Async Update multiple entities
await dapperService.UpdateListAsync(products);

// Delete multiple entities
dapperService.DeleteList(products);

// Async Delete multiple entities
await dapperService.DeleteListAsync(products);

Entity Tracking

// Attach entity for tracking
var entity = new Product { Id = 1, Name = "Original Name", Price = 10.99m };
dapperService.Attach(entity);

// Modify tracked entity
entity.Name = "Updated Name";
entity.Price = 15.99m;

// Update will only update changed properties
dapperService.Update(entity);

// Detach entity from tracking
dapperService.Detach(entity);

Stored Procedures

// Execute stored procedure returning single result set
var results = dapperService.ExecuteStoredProcedure<Customer>(
    "GetCustomersByRegion",
    new { RegionId = 1 }
);
// Execute stored procedure with multiple result sets
// Please note that this property utilizes a local Dapper data type named **GridReader**.
// Therefore, to use this feature, you must add the **Dapper** library to your project references.

var complexResult = dapperService.ExecuteMultiResultStoredProcedure<OrderSummary>(
    "GetOrderSummary",
    reader => {
        var orders = reader.Read<Order>().ToList();
        var details = reader.Read<OrderDetail>().ToList();
        return new OrderSummary { Orders = orders, Details = details };
    },
    new { CustomerId = 1 }
);
or
var complexResult = dapperService.ExecuteMultiResultStoredProcedure(
    "usp_GetDashboardData",
    gr => new {
        Users = gr.Read<User>(),
        Orders = gr.Read<Order>(),
        Stats = gr.Read<DashboardStats>().FirstOrDefault()
    },
    new { Year = 2023 }
);

// Async multiple result sets
var complexResultAsync = await dapperService.ExecuteMultiResultStoredProcedureAsync<OrderSummary>(
    "GetOrderSummary",
    async reader => {
        var orders = (await reader.ReadAsync<Order>()).ToList();
        var details = (await reader.ReadAsync<OrderDetail>()).ToList();
        return new OrderSummary { Orders = orders, Details = details };
    },
    new { CustomerId = 1 }
);

Functions

// Execute scalar function
var totalValue = dapperService.ExecuteScalarFunction<decimal>(
    "CalculateOrderTotal",
    new { OrderId = 1 }
);

// Execute table-valued function
var orderItems = dapperService.ExecuteTableFunction<OrderItem>(
    "GetOrderItems",
    new { OrderId = 1 }
);

Basic Querying


// Simple query with where clause
var users = dapperService.Query<User>()
    .Where(u => u.Age > 18 || u.Name.Contains("m") && u.IsActive == true)
    .Execute();

// Async execution
var usersAsync = await dapperService.Query<User>()
    .Where(u => u.Age > 18)
    .ExecuteAsync();

// Execute with different result type
var dtos = dapperService.Query<User>()
    .Where(u => u.Age > 18)
    .Execute<UserDTO>();

//You can build your expressions separately and then connect them to the query at the end
var expressions = new List<Expression<Func<Person, bool>>>();
expressions.Add(x => x.PARTY_ID == 2);
expressions.Add(x=> x.IdNumber == "450");
var Query = SQL.Query<Person>();
foreach (var expression in expressions)
{
    Query = Query.Where(expression);
}
var result = Query.Execute();

Select Specific Columns

var results = dapperService.Query<User>()
    .Select(u => u.Name, u => u.Email)
    .Execute();

Pagination

// Only from SQL 2012 and later
// Paging Always Must use with OrderBy
var pageSize = 10;
var pageNumber = 1;
var results = dapperService.Query<User>()
    .Paging(pageSize, pageNumber)
    .OrderByAscending(x => x.Name)
    .Execute();

Order

var order = dapperService.Query<Goods>()
.Where(x => x.GoodsId > 1000)
.OrderByDescending(x => new { x.GoodsId, x.Name })
.Execute();

var order2 = dapperService.Query<Goods>()
.Where(x => x.GoodsId > 1000)
.OrderByAscending(x => x.Name)
.Execute();

var order3 = dapperService.Query<Goods>()
.Where(x => x.GoodsId > 1000)
.OrderBy("Name ASC, GoodsCode DESC")
.Execute();

Joins

var result = dapperService.Query<Person>()
.InnerJoin<Person, Party>((x, p) => x.PARTY_ID == p.PartyId)
.Execute();

var result = dapperService.Query<Person>()
.InnerJoin<Person, Party>((x, p) => x.PARTY_ID == p.PartyId)
.LeftJoin<Person, Party>((x, p) => p.PartyId == x.PARTY_ID)
.Select<Party>(x => x.Party_Code)
.Top(10)
.Where(x => x.PARTY_ID == 129 && x.CurrentFirstName.Contains("س"))
.Execute();

APPLY Operations

// Cross Apply
var results = queryBuilder
    .CrossApply<SubQuery>((main, sub) => main.Id == sub.MainId,
        subQuery => subQuery.Where(s => s.Value > 100))
    .Execute();
// without subquery
var results = queryBuilder
    .CrossApply<SubQuery>((main, sub) => main.Id == sub.MainId,null)
    .Execute();

// Outer Apply
var results = dapperService.Query<Person>()
.InnerJoin<Person, Party>((x, p) => x.PARTY_ID == p.PartyId)
.OuterApply<Party>(
    (x, p) => x.PARTY_ID == p.PartyId,
    subQuery => subQuery.Where(a => a.PartyId == 117))
.Where(x => x.PARTY_ID == 117 && x.CurrentFirstName.Contains("J"))
.Execute();

Row Numbers

var results = dapperService.Query<Person>()
    .Row_Number(u => u.Department, u => u.Salary)
    .Execute();

var results = dapperService.Query<Person>()
    .Row_Number(x => new {x.PersonNumber,x.PersonCode}, x => x.Name, "Rows")
    .Execute<PersonDto>()

Set Operations

// Distinct
var results = dapperService.Query<Person>()
    .Select(x=> x.Name)
    .Distinct()
    .Execute();

// Top
var results = dapperService.Query<Person>()
    .Top(10)
    .Execute();

// Union
var result = dapperService.Query<Person>();
var result2 = dapperService.Query<Person>().Where(x=> x.Age > 10);
var res = result.Union(result2).Execute();

Complex Query Example

var results = dapperService.Query<Person>()
    .Select(u => u.Name, u => u.Department)
    .InnerJoin<User, Department>((u, d) => u.DepartmentId == d.Id)
    .Where(u => u.Age > 25)
    .GroupBy(u => u.Department)
    .Having(g => g.Count() > 5)
    .OrderBy("Department ASC")
    .Paging(10, 1)
    .Execute<PersonDto>();

Warning

Keep in mind that your code will ultimately be translated into T-SQL commands. Therefore, logically, it must align with the structure of SQL queries.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Product 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.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.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 net45 is compatible.  net451 was computed.  net452 was computed.  net46 was computed.  net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.0 15 9/13/2025
1.0.8 182 8/27/2025
1.0.7 153 8/24/2025
1.0.6 163 3/12/2025
1.0.5 162 3/11/2025
1.0.4 176 3/11/2025
1.0.3 165 3/11/2025
1.0.2 139 3/9/2025
1.0.1 125 3/9/2025