# Dapper.SimpleCRUD adds the boring queries to IDbConnection as extension methods

> Dapper.SimpleCRUD is a single C# file of extension methods that gives Dapper a Get, Insert, Update and Delete for a mapped class, with table, key and column names read from attributes. It is a convenience layer, not a data mapper, and it deliberately requires an open connection and leaves anything more complex to Dapper's own Query and Execute methods.

**ericdc1/Dapper.SimpleCRUD** — Who wants to write basic read/insert/update/delete statements? SimpleCRUD provides simple CRUD helpers for Dapper.

- Repository: https://github.com/ericdc1/Dapper.SimpleCRUD
- Stars: 1,161 · Forks: 403
- Language: C#
- License: NOASSERTION
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/ericdc1-dapper-simplecrud

## One file, dropped into the project

The premise is stated in the first line of the README and it is unusual for a NuGet package. Dapper.SimpleCRUD is a single file, SimpleCRUD.cs, that you can drop into your project, and it extends your IDbConnection interface. If you want dynamic support you need an additional file, SimpleCRUDAsync.cs.

The motivation paragraph explains the design better than a feature list would. The author wanted simple CRUD operations with smart defaults and without anything extra, and says the existing Dapper extensions did not fit the pattern they had in mind. Two specific requirements are stated. The first is models with additional properties that do not map to the database, for example a FullName property that combines FirstName and LastName in its getter, and that FullName should not be added to the insert and update statements. The second is convention over configuration for naming: the primary key column should be Id in most cases, and the table name should match the class name, both with an attribute as the override.

The repository reflects a project built by a single author rather than a framework with a committee. The top level holds the library directory Dapper.SimpleCRUD/, a test project Dapper.SimpleCRUDTests/, a separate Dapper.SimpleCRUD.ModelGenerator/ project, a solution file, a .nuspec, a NuGet.exe, a package.bat script, a packages/ directory and a History.txt changelog. The licence is a custom one, in License.txt, which GitHub does not classify among the standard licences, so anyone embedding this in a shipped product has to read that file.

## The attribute set decides table, key and column names

The mapping conventions are the part of the library that has real design content, and the README documents them precisely.

The default table name matches the model name, and the default column name matches the property name. Both can be overridden. The [Table] attribute can come from the Dapper namespace, from System.ComponentModel.DataAnnotations.Schema, or from System.Data.Linq.Mapping, and the [Key] attribute can come from the Dapper namespace or from System.ComponentModel.DataAnnotations. The [Column] attribute has the same three sources.

The interesting detail is what happens in the where clause. The README states that you can use the model property names in the where clause anonymous object and SimpleCRUD will generate a proper where clause to match the database based on the column attribute. So the object you pass as the filter is written in terms of the model, and the library translates it to the renamed column.

The example shows the shape of it. A plain class with Id, Name and Age produces this.

```sql
Select Id, Name, Age from [User] where Id = 1
```

The attributed version renames the table, renames the key and renames one column, and the generated statement follows.

```sql
Select UserId, strFirstName as FirstName, LastName, Age from [Users] where UserId = @UserID
```

The as FirstName in the select list is the mechanism for the computed property case from the introduction: a getter that derives a value from other columns is not in the column list, but the column it derives from is, and the alias brings the name back to the property.

## The helper list is deliberately short

The README says this extension adds eight helpers, and then lists more than eight, which is a fair sign that the surface grew over time. Reading them is the fastest way to understand the intended usage.

On the read side there is Get(id) for a single record by primary key, GetList with no arguments for every record, GetList with an anonymous object for the where clause, GetList with a conditions string plus an anonymous object of parameters, GetListPaged taking a page number, an items per page, conditions, an order clause and parameters, and RecordCount with conditions and parameters.

On the write side there is Insert(entity), which returns the new primary key and assumes an int primary key, and a second overload Insert<Guid,T>(entity) that returns a new guid primary key. Update(entity) updates a record. Delete has three forms, by id with the type parameter, by typed entity, and DeleteList in both the anonymous object and the conditions string variants.

GUID primary keys are supported, and the README notes they autopopulate if no value is passed in.

Two features in that list deserve comment because they are where a simple library meets a real database. GetListPaged takes a page number and an items per page rather than a limit and an offset, which means the paging has to be translated into whatever dialect the database speaks. And Insert with a guid overload has to read the generated key back, which is a different code path per provider.

The README also says plainly: if you need something more complex use Dapper's Query or Execute methods. The library is not trying to grow into a query builder, and the escape hatch is documented at the point where you would look for it.

## Async support is a separate file and a separate decision

For projects targeting .NET 4.5 or later, the README lists the same set of helpers with an Async suffix: GetAsync, GetListAsync, GetListPagedAsync, InsertAsync including the guid overload, UpdateAsync, DeleteAsync by id and by entity, DeleteListAsync, and RecordCountAsync.

What is easy to miss is the packaging detail. The first paragraph says the library is a single file you can drop into your project, and that if you want dynamic support you need an additional file, SimpleCRUDAsync.cs. So the async helpers are not in the same file, and a project that copies only SimpleCRUD.cs has no async methods at all.

That is the trade-off of the single file approach, and it cuts both ways. In exchange for not taking a package dependency, you end up with source in your repository that you are responsible for updating, and a second file whose presence changes what compiles. The project does ship a NuGet package at nuget.org/packages/Dapper.SimpleCRUD, so the copy in your repository is a choice rather than a requirement, but the README is written around the drop in model.

The Dapper.SimpleCRUD.ModelGenerator directory is the related piece for teams that would rather not hand write POCOs. It is published as its own NuGet package, Dapper.SimpleCRUD.ModelGenerator, described as a T4 template to generate your POCOs, with documentation in the project wiki under T4 Template.

## The connection has to be open before you call anything

There is one operational rule in the README, and it is stated as a note rather than as a rule: all extension methods assume the connection is already open, and they will fail if the connection is closed.

That is a deliberate design choice rather than an oversight. A helper that opened and closed the connection for every call would be simpler to use in isolation and useless in a transaction, and it would hide the connection lifetime from the code that owns it. The cost is that the calling code has to manage the lifetime, and the failure mode when it does not is a runtime error rather than a compile time one.

For a .NET team this is not a large cost, since opening a connection is usually the caller's job anyway, but it does mean the library composes with ADO.NET patterns rather than hiding them. It also means the same call site behaves differently in and out of a transaction depending on who opened the connection.

The second limitation follows from the first design goal. Because the whole point is to keep the SQL out of your code, the helper set covers table level operations only. There is no join helper, no aggregation other than a count, no transaction helper and no query builder, and the generated SQL is fixed per operation. A schema with inheritance, a table with a composite key, or a query that needs three tables joined is outside what these methods can express, and the README's answer to that is to drop down to Dapper.

## Installing is a NuGet package or a copied file

There is no build step, no tool to run and no configuration to write, which is the point of the design.

The package route is the NuGet package, and the README gives its address directly at nuget.org/packages/Dapper.SimpleCRUD. The copy route is to take SimpleCRUD.cs from the repository and add it to your project, adding SimpleCRUDAsync.cs as well if you want the async helpers and the dynamic support.

The first use looks like the example in the README. The model is a plain class with three properties.

```csharp
public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}
```

And the call is a single extension method on the connection, with the id as the argument.

```csharp
var user = connection.Get<User>(1);
```

The one thing to get right before that call compiles is the connection. Since every method assumes an open connection, the first line of your code has to be whatever opens it, and the README does not document a helper for that, which leaves it to the surrounding code base.

## Conclusion

Dapper.SimpleCRUD suits a .NET team that has already chosen Dapper and wants to stop writing the same insert and update statements for every table, without adopting a full ORM or a code generator for the whole project. It is the wrong tool for anything beyond table level CRUD, since the helper set stops where the query stops being simple. Verify first that your connection lifetime is managed outside the call, because every extension method assumes the connection is already open, and decide early whether you want the extra SimpleCRUDAsync.cs file, since dynamic support depends on it being present.

## FAQ

### What does Dapper.SimpleCRUD add to Dapper?

It adds extension methods on IDbConnection for Get, GetList, GetListPaged, Insert, Update, Delete, DeleteList and RecordCount, with matching Async variants for .NET 4.5 and later. The README says that for anything more complex you should use Dapper's own Query or Execute methods.

### How do I map a model to a table and columns?

By default the table name matches the model name and the column names match the property names, and both can be overridden with the [Table] and [Column] attributes, which can be taken from the Dapper namespace, System.ComponentModel.DataAnnotations.Schema or System.Data.Linq.Mapping. The primary key defaults to Id and can be overridden with the [Key] attribute.

### Does the connection need to be open?

Yes. The README notes that all extension methods assume the connection is already open and that they will fail if the connection is closed. Opening the connection is left to the calling code.

### How do I get the async methods?

The library is a single file, SimpleCRUD.cs, and dynamic support needs the additional file SimpleCRUDAsync.cs, which holds the async helpers for .NET 4.5 and later. The package is also available on NuGet as Dapper.SimpleCRUD.

### Can it generate my POCO classes?

There is a separate model generator project, Dapper.SimpleCRUD.ModelGenerator, published as its own NuGet package and described as a T4 template to generate your POCOs, with documentation in the project wiki.

## Sources

- [ericdc1/Dapper.SimpleCRUD on GitHub](https://github.com/ericdc1/Dapper.SimpleCRUD)
- [Issues](https://github.com/ericdc1/Dapper.SimpleCRUD/issues)
- [README](https://github.com/ericdc1/Dapper.SimpleCRUD/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/ericdc1-dapper-simplecrud
