Home

Awesome

Dapper.SimpleCRUD - simple CRUD helpers for Dapper

Features

<img align="right" src="https://raw.githubusercontent.com/ericdc1/Dapper.SimpleCRUD/master/images/SimpleCRUD-200x200.png" alt="SimpleCRUD"> Dapper.SimpleCRUD is a [single file](https://github.com/ericdc1/Dapper.SimpleCRUD/blob/master/Dapper.SimpleCRUD/SimpleCRUD.cs) you can drop in to your project that will extend your IDbConnection interface. (If you want dynamic support, you need an [additional file](https://github.com/ericdc1/Dapper.SimpleCRUD/blob/master/Dapper.SimpleCRUD/SimpleCRUDAsync.cs).)

Who wants to write basic read/insert/update/delete statements?

The existing Dapper extensions did not fit my ideal pattern. I wanted simple CRUD operations with smart defaults without anything extra. I also wanted to have models with additional properties that did not directly map to the database. For example - a FullName property that combines FirstName and LastName in its getter - and not add FullName to the Insert and Update statements.

I wanted the primary key column to be Id in most cases but allow overriding with an attribute.

Finally, I wanted the table name to match the class name by default but allow overriding with an attribute.

This extension adds the following 8 helpers:

For projects targeting .NET 4.5 or later, the following 8 helpers exist for async operations:

If you need something more complex use Dapper's Query or Execute methods!

Note: all extension methods assume the connection is already open, they will fail if the connection is closed.

Install via NuGet - https://nuget.org/packages/Dapper.SimpleCRUD

Check out the model generator T4 template to generate your POCOs. Documentation is at https://github.com/ericdc1/Dapper.SimpleCRUD/wiki/T4-Template

Get a single record mapped to a strongly typed object

 public static T Get<T>(this IDbConnection connection, int id)

Example basic usage:

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}
      
var user = connection.Get<User>(1);   

Results in executing this SQL

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

More complex example:

    [Table("Users")]
    public class User
    {
        [Key]
        public int UserId { get; set; }
        [Column("strFirstName")]
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
    }
    
    var user = connection.Get<User>(1);  

Results in executing this SQL

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

Notes:

Execute a query and map the results to a strongly typed List

public static IEnumerable<T> GetList<T>(this IDbConnection connection)

Example usage:

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}
var user = connection.GetList<User>();  

Results in

Select * from [User]

Execute a query with where conditions and map the results to a strongly typed List

public static IEnumerable<T> GetList<T>(this IDbConnection connection, object whereConditions)

Example usage:

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}
  
var user = connection.GetList<User>(new { Age = 10 });  

Results in

Select * from [User] where Age = @Age

Notes:

Execute a query with a where clause and map the results to a strongly typed List

public static IEnumerable<T> GetList<T>(this IDbConnection connection, string conditions, object parameters = null)

Example usage:

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}
  
var user = connection.GetList<User>("where age = 10 or Name like '%Smith%'");  

or with parameters

var encodeForLike = term => term.Replace("[", "[[]").Replace("%", "[%]");
string likename = "%" + encodeForLike("Smith") + "%";
var user = connection.GetList<User>("where age = @Age or Name like @Name", new {Age = 10, Name = likename});  

Results in

Select * from [User] where age = 10 or Name like '%Smith%'

Notes:

Execute a query with a where clause and map the results to a strongly typed List with Paging

public static IEnumerable<T> GetListPaged<T>(this IDbConnection connection, int pageNumber, int rowsPerPage, string conditions, string orderby, object parameters = null)

Example usage:

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}
  
var user = connection.GetListPaged<User>(1,10,"where age = 10 or Name like '%Smith%'","Name desc");  

Results in (SQL Server dialect)

SELECT * FROM (SELECT ROW_NUMBER() OVER(ORDER BY Name desc) AS PagedNumber, Id, Name, Age FROM [User] where age = 10 or Name like '%Smith%') AS u WHERE PagedNUMBER BETWEEN ((1 - 1) * 10 + 1) AND (1 * 10)

or with parameters

var user = connection.GetListPaged<User>(1,10,"where age = @Age","Name desc", new {Age = 10});  

Results in (SQL Server dialect)

SELECT * FROM (SELECT ROW_NUMBER() OVER(ORDER BY Name desc) AS PagedNumber, Id, Name, Age FROM [User] where age = 10) AS u WHERE PagedNUMBER BETWEEN ((1 - 1) * 10 + 1) AND (1 * 10)

Notes:

Insert a record

public static int Insert(this IDbConnection connection, object entityToInsert)

Example usage:

[Table("Users")]
public class User
{
   [Key]
   public int UserId { get; set; }
   public string FirstName { get; set; }
   public string LastName { get; set; }
   public int Age { get; set; }

   //Additional properties not in database
   [Editable(false)]
   public string FullName { get { return string.Format("{0} {1}", FirstName, LastName); } }
   public List<User> Friends { get; set; }
   [ReadOnly(true)]
   public DateTime CreatedDate { get; set; }
}

var newId = connection.Insert(new User { FirstName = "User", LastName = "Person",  Age = 10 });  

Results in executing this SQL

Insert into [Users] (FirstName, LastName, Age) VALUES (@FirstName, @LastName, @Age)

Notes:

Insert a record with Guid key

public static int Insert<Guid,T>(this IDbConnection connection, object entityToInsert)

Example usage:

[Table("Users")]
public class User
{
   [Key]
   public Guid GuidKey { get; set; }
   public string FirstName { get; set; }
   public string LastName { get; set; }
   public int Age { get; set; }
}

var newGuid = connection.Insert<Guid,User>(new User { FirstName = "User", LastName = "Person",  Age = 10 });  

Results in executing this SQL

Insert into [Users] (FirstName, LastName, Age) VALUES (@FirstName, @LastName, @Age)

Update a record

public static int Update(this IDbConnection connection, object entityToUpdate)

Example usage:

[Table("Users")]
public class User
{
   [Key]
   public int UserId { get; set; }
   [Column("strFirstName")]
   public string FirstName { get; set; }
   public string LastName { get; set; }
   public int Age { get; set; }

   //Additional properties not in database
   [Editable(false)]
   public string FullName { get { return string.Format("{0} {1}", FirstName, LastName); } }
   public List<User> Friends { get; set; }
}
connection.Update(entity);

Results in executing this SQL

Update [Users] Set (strFirstName=@FirstName, LastName=@LastName, Age=@Age) Where ID = @ID

Notes:

Delete a record

public static int Delete<T>(this IDbConnection connection, int Id)

Example usage:

public class User
{
   public int Id { get; set; }
   public string FirstName { get; set; }
   public string LastName { get; set; }
   public int Age { get; set; }
}
connection.Delete<User>(newid);

Or

public static int Delete<T>(this IDbConnection connection, T entityToDelete)

Example usage:

public class User
{
   public int Id { get; set; }
   public string FirstName { get; set; }
   public string LastName { get; set; }
   public int Age { get; set; }
}

connection.Delete(entity);

Results in executing this SQL

Delete From [User] Where ID = @ID

Delete multiple records with where conditions

public static int DeleteList<T>(this IDbConnection connection, object whereConditions, IDbTransaction transaction = null, int? commandTimeout = null)

Example usage:

connection.DeleteList<User>(new { Age = 10 });

Delete multiple records with where clause

public static int DeleteList<T>(this IDbConnection connection, string conditions, object parameters = null, IDbTransaction transaction = null, int? commandTimeout = null)

Example usage:

connection.DeleteList<User>("Where age > 20");

or with parameters

connection.DeleteList<User>("Where age > @Age", new {Age = 20});

Get count of records

public static int RecordCount<T>(this IDbConnection connection, string conditions = "", object parameters = null)

Example usage:

var count = connection.RecordCount<User>("Where age > 20");

or with parameters

var count = connection.RecordCount<User>("Where age > @Age", new {Age = 20});

Custom table and column name resolvers

You can also change the format of table and column names, first create a class implimenting the ITableNameResolver and/or IColumnNameResolver interfaces

public class CustomResolver : SimpleCRUD.ITableNameResolver, SimpleCRUD.IColumnNameResolver
{
    public string ResolveTableName(Type type)
    {
        return string.Format("tbl_{0}", type.Name);
    }

    public string ResolveColumnName(PropertyInfo propertyInfo)
    {
        return string.Format("{0}_{1}", propertyInfo.DeclaringType.Name, propertyInfo.Name);
    }
}

then apply the resolvers when intializing your application

    var resolver = new CustomResolver();
    SimpleCRUD.SetTableNameResolver(resolver);
    SimpleCRUD.SetColumnNameResolver(resolver);

Database support

   SimpleCRUD.SetDialect(SimpleCRUD.Dialect.PostgreSQL);
    
   SimpleCRUD.SetDialect(SimpleCRUD.Dialect.MySQL);

Attributes

The following attributes can be applied to properties in your model

[Table("YourTableName")] - By default the database table name will match the model name but it can be overridden with this.

[Column("YourColumnName"] - By default the column name will match the property name but it can be overridden with this. You can even 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

[Key] -By default the Id integer field is considered the primary key and is excluded from insert. The [Key] attribute lets you specify any Int or Guid as the primary key.

[Required] - By default the [Key] property is not inserted as it is expected to be an autoincremented by the database. You can mark a property as a [Key] and [Required] if you want to specify the value yourself during the insert.

[Editable(false)] - By default the select, insert, and update statements include all properties in the class - The Editable(false) and attribute excludes the property from being included. A good example for this is a FullName property that is derived from combining FirstName and Lastname in the model but the FullName field isn't actually in the database. Complex types are not included in the insert statement - This keeps the List out of the insert even without the Editable attribute.

[ReadOnly(true)] - Properties decorated with ReadOnly(true) are only used for selects and are excluded from inserts and updates. This would be useful for fields like CreatedDate where the database generates the date on insert and you never want to modify it.

[IgnoreSelect] - Excludes the property from selects

[IgnoreInsert] - Excludes the property from inserts

[IgnoreUpdate] - Excludes the property from updates

[NotMapped] - Excludes the property from all operations

Do you have a comprehensive list of examples?

Dapper.SimpleCRUD has a basic test suite in the test project