Performing Inserts and Updates with Dapper
Asked Answered
P

9

250

I am interested in using Dapper - but from what I can tell it only supports Query and Execute. I do not see that Dapper includes a way of Inserting and Updating objects.

Given that our project (most projects?) need to do inserts and updates, what is the best practice for doing Inserts and Updates alongside dapper?

Preferably we would not have to resort to the ADO.NET method of parameter building, etc.

The best answer I can come up with at this point is to use LinqToSQL for inserts and updates. Is there a better answer?

Psychodiagnosis answered 10/5, 2011 at 23:54 Comment(2)
Contrib has moved github.com/DapperLib/Dapper.ContribWinter
The short, short version: Execute can be used to run insert or update queries. Match the parameter names in your query to your C# property names and pass your C# entity as the parameters, viz: conn.Execute("INSERT Person VALUES(@Name, @Age)", person);Contestation
F
257

We are looking at building a few helpers, still deciding on APIs and if this goes in core or not. See: https://code.google.com/archive/p/dapper-dot-net/issues/6 for progress.

In the mean time you can do the following

val = "my value";
cnn.Execute("insert into Table(val) values (@val)", new {val});

cnn.Execute("update Table set val = @val where Id = @id", new {val, id = 1});

etcetera

See also my blog post: That annoying INSERT problem

Update

As pointed out in the comments, there are now several extensions available in the Dapper.Contrib project in the form of these IDbConnection extension methods:

T Get<T>(id);
IEnumerable<T> GetAll<T>();
int Insert<T>(T obj);
int Insert<T>(Enumerable<T> list);
bool Update<T>(T obj);
bool Update<T>(Enumerable<T> list);
bool Delete<T>(T obj);
bool Delete<T>(Enumerable<T> list);
bool DeleteAll<T>();
Foretop answered 11/5, 2011 at 12:45 Comment(15)
Hi Sam, found your SO answer with google and I was wondering if the last line of code should include the word set as cnn.Execute("update Table SET val = @val where Id = @id", new {val, id = 1}); or is this dapper specific? I am new to dapper and was looking for an update example :)Riehl
@JPHellemons I tried this var updateCat = connection.Execute("UPDATE tCategories SET sCategory = @val WHERE iCategoryID = @id", new { val = "dapper test", id = 23 }); and it worked. Without the use of SET I get a SQLException syntax error near sCategory.Oleaster
Fast forward to Dec 2015: github.com/StackExchange/dapper-dot-net/tree/master/…Crum
It will be possible to execute both in the same statement? like cnn.Query("insert Table(val) values (@val); update Table set val = @val where Id = @Id", new { val = 1, id = 1 } it seems to fail when combinedLorenza
@RosdiKasim Doesn't this defeat the purpose of using Dapper? I want to use SQL. This abstracts it. What am I missing?Bullins
@Bullins It is just helper class... some people wants their code as succinct as possible... you don't have to use it if you dont want it.Crum
@RosdiKasim Sorry if that came off wrong. I was only trying to understand. New to using any of them.Bullins
does it work for Sqlite, I tried it after on Sqlite and doesn't show anything like this in intellisense.Siamese
I hope it's useful to give a link here to an article where I show how Rob Conery's Massive used yet another interesting solution to "That Annoying INSERT Problem", one that Sam Saffron's blog post didn't cover. medium.com/@mikebeaton/…Leek
Dapper using Update with OUTPUT clause sqlservercentral.com/articles/… ?Catechol
Can anyone please tell me what the duck is the long identifier returned by the Insert extension? My table's primary key is a non-numeric string (VARCHAR), and actually the only thing I want to know after calling Insert is whether the row was successfully inserted or an error happened, how do I know that?Thor
Fast forward to July 2021: github.com/DapperLib/Dapper.ContribNero
Is it possible to make column names dynamic? like: cnn.Execute("insert into Table() values (@)", TableMatchingClass);Bobbiebobbin
be aware that Dapper.Contrib has issues when your data class has navigation properties, to deal with that you need to use [Write(false)] as an attribute and add a separate property with the name of the foreign key column. In theory you could use Dapper.Extensions, however that tool has - since 2021 - issues when used in a multithread/async environment. See here and hereBurglar
Dapper.Contrib doesn't honor the Dapper setting MatchNamesWithUnderscores making it useless/trouble to anyone who relies on that. This issue has lingered for years and doesn't look like being fixedElmaelmajian
T
102

Performing CRUD operations using Dapper is an easy task. I have mentioned the below examples that should help you in CRUD operations.

Code for CRUD:

Method #1: This method is used when you are inserting values from different entities.

using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["myDbConnection"].ConnectionString))
{
    string insertQuery = @"INSERT INTO [dbo].[Customer]([FirstName], [LastName], [State], [City], [IsActive], [CreatedOn]) VALUES (@FirstName, @LastName, @State, @City, @IsActive, @CreatedOn)";

    var result = db.Execute(insertQuery, new
    {
        customerModel.FirstName,
        customerModel.LastName,
        StateModel.State,
        CityModel.City,
        isActive,
        CreatedOn = DateTime.Now
    });
}

Method #2: This method is used when your entity properties have the same names as the SQL columns. So, Dapper being an ORM maps entity properties with the matching SQL columns.

using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["myDbConnection"].ConnectionString))
{
    string insertQuery = @"INSERT INTO [dbo].[Customer]([FirstName], [LastName], [State], [City], [IsActive], [CreatedOn]) VALUES (@FirstName, @LastName, @State, @City, @IsActive, @CreatedOn)";

    var result = db.Execute(insertQuery, customerViewModel);
}

Code for CRUD:

using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["myDbConnection"].ConnectionString))
{
    string selectQuery = @"SELECT * FROM [dbo].[Customer] WHERE FirstName = @FirstName";

    var result = db.Query(selectQuery, new
    {
        customerModel.FirstName
    });
}

Code for CRUD:

using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["myDbConnection"].ConnectionString))
{
    string updateQuery = @"UPDATE [dbo].[Customer] SET IsActive = @IsActive WHERE FirstName = @FirstName AND LastName = @LastName";

    var result = db.Execute(updateQuery, new
    {
        isActive,
        customerModel.FirstName,
        customerModel.LastName
    });
}

Code for CRUD:

using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["myDbConnection"].ConnectionString))
{
    string deleteQuery = @"DELETE FROM [dbo].[Customer] WHERE FirstName = @FirstName AND LastName = @LastName";

    var result = db.Execute(deleteQuery, new
    {
        customerModel.FirstName,
        customerModel.LastName
    });
}
Tahr answered 3/7, 2016 at 8:9 Comment(0)
G
29

you can do it in such way:

sqlConnection.Open();

string sqlQuery = "INSERT INTO [dbo].[Customer]([FirstName],[LastName],[Address],[City]) VALUES (@FirstName,@LastName,@Address,@City)";
sqlConnection.Execute(sqlQuery,
    new
    {
        customerEntity.FirstName,
        customerEntity.LastName,
        customerEntity.Address,
        customerEntity.City
    });

Edit added by Caius:

Note that it's not necessary to open/close the connection in this "immediately before/after the operation" way: if your connection is closed, Dapper opens it. If your connection is open, Dapper leaves it open.

Open the connection yourself if you e.g. have many operations to perform/you're using a transaction. Leave Dapper to do it if all you'll do is open/execute/close.

Also, it's unnecessary to make an anonymous type; just make your parameters names match your property names in whatever type holds your data, and pass that type rather than unpacking it to an anonymous type.

The code above can be written thus:

string sqlQuery = "INSERT INTO [dbo].[Customer]([FirstName],[LastName],[Address],[City]) VALUES (@FirstName,@LastName,@Address,@City)";

using(var sqlConnection = ...){
  sqlConnection.Execute(sqlQuery, customerEntity);

}
Grenadier answered 5/7, 2011 at 7:17 Comment(6)
You should use using-statement so that the connection gets closed even in case of an exception.Levis
you could just pass customerEntity directly instead of using an anonymous type...Sesquicarbonate
@ThomasLevesque What do you mean by that? Can you provide a tiny code example of what you mean?Weatherby
@iaacp, I mean that: sqlConnection.Execute(sqlQuery, customerEntity);Sesquicarbonate
@ThomasLevesque can we do update also using the same pattern? i.e., sqlConnection.Execute(sqlQuery, customerEntity);Kunz
@Kunz yes you can. Match your @parameter names to be equal to your c# property names and you can put whatever sql statement you like into ExecuteContestation
P
28

Using Dapper.Contrib it is as simple as this:

Insert list:

public int Insert(IEnumerable<YourClass> yourClass)
{
    using (SqlConnection conn = new SqlConnection(ConnectionString))
    {
        return conn.Insert(yourClass) ;
    }
}

Insert single:

public int Insert(YourClass yourClass)
{
    using (SqlConnection conn = new SqlConnection(ConnectionString))
    {
        return conn.Insert(yourClass) ;
    }
}

Update list:

public bool Update(IEnumerable<YourClass> yourClass)
{
    using (SqlConnection conn = new SqlConnection(ConnectionString))
    {
        return conn.Update(yourClass) ;
    }
}

Update single:

public bool Update(YourClass yourClass)
{
    using (SqlConnection conn = new SqlConnection(ConnectionString))
    {
        return conn.Update(yourClass) ;
    }
}

Source: https://github.com/StackExchange/Dapper/tree/master/Dapper.Contrib

Pressor answered 24/4, 2017 at 20:2 Comment(5)
Using the above to insert a single object you can get the new identity number back out and put it back in your model... But how do you do it for inserting a list of objects - the objects in the list doesn't have the identity field. Do you have to iterate through the list and then insert them one at a time, getting the new ID out each time?Photo
@harag If you need the new ID somewhere else I guess you have to do it like that. Entity Framework handles reference types, like classes, without a problem with inserts but I don't know how Dapper.Contrib works with that if that was your angle.Pressor
@Ogglas, thanks. I've noticed "connection.Insert(myObject)" will update the "[key]" property of the "myObject" if I'm just inserting one object, but if I'm inserting a list of say 5 objects using the same "connection.Insert(myObjectList)" then none of the [keys] properties are updated, so I have to manually do foreach item in list and insert them one at a time.Photo
In conn.Update(yourClass) if some properties are null, then UPDATE the fields to NULL ? Not working. Update field to NULL. Not partials updatesCatechol
how does your model looks like ? I mean, how does it know what table in what schema to do the insert or update ?Hypodermis
M
9

You can also use dapper with a stored procedure and generic way by which everything easily manageable.

Define your connection:

public class Connection: IDisposable
{
    private static SqlConnectionStringBuilder ConnectionString(string dbName)
    {
        return new SqlConnectionStringBuilder
            {
                ApplicationName = "Apllication Name",
                DataSource = @"Your source",
                IntegratedSecurity = false,
                InitialCatalog = Database Name,
                Password = "Your Password",
                PersistSecurityInfo = false,
                UserID = "User Id",
                Pooling = true
            };
    }

    protected static IDbConnection LiveConnection(string dbName)
    {
        var connection = OpenConnection(ConnectionString(dbName));
        connection.Open();
        return connection;
    }

    private static IDbConnection OpenConnection(DbConnectionStringBuilder connectionString)
    {
        return new SqlConnection(connectionString.ConnectionString);
    }

    protected static bool CloseConnection(IDbConnection connection)
    {
        if (connection.State != ConnectionState.Closed)
        {
            connection.Close();
            // connection.Dispose();
        }
        return true;
    }

    private static void ClearPool()
    {
        SqlConnection.ClearAllPools();
    }

    public void Dispose()
    {
        ClearPool();
    }
}

Create an interface to define Dapper methods those you actually need:

 public interface IDatabaseHub
    {
   long Execute<TModel>(string storedProcedureName, TModel model, string dbName);

        /// <summary>
        /// This method is used to execute the stored procedures with parameter.This is the generic version of the method.
        /// </summary>
        /// <param name="storedProcedureName">This is the type of POCO class that will be returned. For more info, refer to https://msdn.microsoft.com/en-us/library/vstudio/dd456872(v=vs.100).aspx. </param>
        /// <typeparam name="TModel"></typeparam>
        /// <param name="model">The model object containing all the values that passes as Stored Procedure's parameter.</param>
        /// <returns>Returns how many rows have been affected.</returns>
        Task<long> ExecuteAsync<TModel>(string storedProcedureName, TModel model, string dbName);

        /// <summary>
        /// This method is used to execute the stored procedures with parameter. This is the generic version of the method.
        /// </summary>
        /// <param name="storedProcedureName">Stored Procedure's name. Expected to be a Verbatim String, e.g. @"[Schema].[Stored-Procedure-Name]"</param>
        /// <param name="parameters">Parameter required for executing Stored Procedure.</param>        
        /// <returns>Returns how many rows have been affected.</returns>         
        long Execute(string storedProcedureName, DynamicParameters parameters, string dbName);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="storedProcedureName"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        Task<long> ExecuteAsync(string storedProcedureName, DynamicParameters parameters, string dbName);
}

Implement the interface:

     public class DatabaseHub : Connection, IDatabaseHub
        {

 /// <summary>
        /// This function is used for validating if the Stored Procedure's name is correct.
        /// </summary>
        /// <param name="storedProcedureName">Stored Procedure's name. Expected to be a Verbatim String, e.g. @"[Schema].[Stored-Procedure-Name]"</param>
        /// <returns>Returns true if name is not empty and matches naming patter, otherwise returns false.</returns>

        private static bool IsStoredProcedureNameCorrect(string storedProcedureName)
        {
            if (string.IsNullOrEmpty(storedProcedureName))
            {
                return false;
            }

            if (storedProcedureName.StartsWith("[") && storedProcedureName.EndsWith("]"))
            {
                return Regex.IsMatch(storedProcedureName,
                    @"^[\[]{1}[A-Za-z0-9_]+[\]]{1}[\.]{1}[\[]{1}[A-Za-z0-9_]+[\]]{1}$");
            }
            return Regex.IsMatch(storedProcedureName, @"^[A-Za-z0-9]+[\.]{1}[A-Za-z0-9]+$");
        }

     /// <summary>
            /// This method is used to execute the stored procedures without parameter.
            /// </summary>
            /// <param name="storedProcedureName">Stored Procedure's name. Expected to be a Verbatim String, e.g. @"[Schema].[Stored-Procedure-Name]"</param>
            /// <param name="model">The model object containing all the values that passes as Stored Procedure's parameter.</param>
            /// <typeparam name="TModel">This is the type of POCO class that will be returned. For more info, refer to https://msdn.microsoft.com/en-us/library/vstudio/dd456872(v=vs.100).aspx. </typeparam>
            /// <returns>Returns how many rows have been affected.</returns>

            public long Execute<TModel>(string storedProcedureName, TModel model, string dbName)
            {
                if (!IsStoredProcedureNameCorrect(storedProcedureName))
                {
                    return 0;
                }

                using (var connection = LiveConnection(dbName))
                {
                    try
                    {
                        return connection.Execute(
                            sql: storedProcedureName,
                            param: model,
                            commandTimeout: null,
                            commandType: CommandType.StoredProcedure
                            );

                    }
                    catch (Exception exception)
                    {
                        throw exception;
                    }
                    finally
                    {
                        CloseConnection(connection);
                    }
                }
            }

            public async Task<long> ExecuteAsync<TModel>(string storedProcedureName, TModel model, string dbName)
            {
                if (!IsStoredProcedureNameCorrect(storedProcedureName))
                {
                    return 0;
                }

                using (var connection = LiveConnection(dbName))
                {
                    try
                    {
                        return await connection.ExecuteAsync(
                            sql: storedProcedureName,
                            param: model,
                            commandTimeout: null,
                            commandType: CommandType.StoredProcedure
                            );

                    }
                    catch (Exception exception)
                    {
                        throw exception;
                    }
                    finally
                    {
                        CloseConnection(connection);
                    }
                }
            }

            /// <summary>
            /// This method is used to execute the stored procedures with parameter. This is the generic version of the method.
            /// </summary>
            /// <param name="storedProcedureName">Stored Procedure's name. Expected to be a Verbatim String, e.g. @"[Schema].[Stored-Procedure-Name]"</param>
            /// <param name="parameters">Parameter required for executing Stored Procedure.</param>        
            /// <returns>Returns how many rows have been affected.</returns>

            public long Execute(string storedProcedureName, DynamicParameters parameters, string dbName)
            {
                if (!IsStoredProcedureNameCorrect(storedProcedureName))
                {
                    return 0;
                }

                using (var connection = LiveConnection(dbName))
                {
                    try
                    {
                        return connection.Execute(
                            sql: storedProcedureName,
                            param: parameters,
                            commandTimeout: null,
                            commandType: CommandType.StoredProcedure
                            );
                    }
                    catch (Exception exception)
                    {
                        throw exception;
                    }
                    finally
                    {
                        CloseConnection(connection);
                    }
                }
            }



            public async Task<long> ExecuteAsync(string storedProcedureName, DynamicParameters parameters, string dbName)
            {
                if (!IsStoredProcedureNameCorrect(storedProcedureName))
                {
                    return 0;
                }

                using (var connection = LiveConnection(dbName))
                {
                    try
                    {
                        return await connection.ExecuteAsync(
                            sql: storedProcedureName,
                            param: parameters,
                            commandTimeout: null,
                            commandType: CommandType.StoredProcedure
                            );

                    }
                    catch (Exception exception)
                    {
                        throw exception;
                    }
                    finally
                    {
                        CloseConnection(connection);
                    }
                }
            }

    }

You can now call from model as your need:

public class DeviceDriverModel : Base
    {
 public class DeviceDriverSaveUpdate
        {
            public string DeviceVehicleId { get; set; }
            public string DeviceId { get; set; }
            public string DriverId { get; set; }
            public string PhoneNo { get; set; }
            public bool IsActive { get; set; }
            public string UserId { get; set; }
            public string HostIP { get; set; }
        }


        public Task<long> DeviceDriver_SaveUpdate(DeviceDriverSaveUpdate obj)
        {

            return DatabaseHub.ExecuteAsync(
                    storedProcedureName: "[dbo].[sp_SaveUpdate_DeviceDriver]", model: obj, dbName: AMSDB);//Database name defined in Base Class.
        }
}

You can also passed parameters as well:

public Task<long> DeleteFuelPriceEntryByID(string FuelPriceId, string UserId)
        {


            var parameters = new DynamicParameters();
            parameters.Add(name: "@FuelPriceId", value: FuelPriceId, dbType: DbType.Int32, direction: ParameterDirection.Input);
            parameters.Add(name: "@UserId", value: UserId, dbType: DbType.String, direction: ParameterDirection.Input);

            return DatabaseHub.ExecuteAsync(
                    storedProcedureName: @"[dbo].[sp_Delete_FuelPriceEntryByID]", parameters: parameters, dbName: AMSDB);

        }

Now call from your controllers:

var queryData = new DeviceDriverModel().DeviceInfo_Save(obj);

Hope it's prevent your code repetition and provide security;

Millenarian answered 13/1, 2019 at 11:22 Comment(0)
V
5

Instead of using any 3rd party library for query operations, I would rather suggest writing queries on your own. Because using any other 3rd party packages would take away the main advantage of using dapper i.e. flexibility to write queries.

Now, there is a problem with writing Insert or Update query for the entire object. For this, one can simply create helpers like below:

InsertQueryBuilder:

 public static string InsertQueryBuilder(IEnumerable < string > fields) {


  StringBuilder columns = new StringBuilder();
  StringBuilder values = new StringBuilder();


  foreach(string columnName in fields) {
   columns.Append($ "{columnName}, ");
   values.Append($ "@{columnName}, ");

  }
  string insertQuery = $ "({ columns.ToString().TrimEnd(',', ' ')}) VALUES ({ values.ToString().TrimEnd(',', ' ')}) ";

  return insertQuery;
 }

Now, by simply passing the name of the columns to insert, the whole query will be created automatically, like below:

List < string > columns = new List < string > {
 "UserName",
 "City"
}
//QueryBuilder is the class having the InsertQueryBuilder()
string insertQueryValues = QueryBuilderUtil.InsertQueryBuilder(columns);

string insertQuery = $ "INSERT INTO UserDetails {insertQueryValues} RETURNING UserId";

Guid insertedId = await _connection.ExecuteScalarAsync < Guid > (insertQuery, userObj);

You can also modify the function to return the entire INSERT statement by passing the TableName parameter.

Make sure that the Class property names match with the field names in the database. Then only you can pass the entire obj (like userObj in our case) and values will be mapped automatically.

In the same way, you can have the helper function for UPDATE query as well:

  public static string UpdateQueryBuilder(List < string > fields) {
   StringBuilder updateQueryBuilder = new StringBuilder();

   foreach(string columnName in fields) {
    updateQueryBuilder.AppendFormat("{0}=@{0}, ", columnName);
   }
   return updateQueryBuilder.ToString().TrimEnd(',', ' ');
  }

And use it like:

List < string > columns = new List < string > {
 "UserName",
 "City"
}
//QueryBuilder is the class having the UpdateQueryBuilder()
string updateQueryValues = QueryBuilderUtil.UpdateQueryBuilder(columns);

string updateQuery =  $"UPDATE UserDetails SET {updateQueryValues} WHERE UserId=@UserId";

await _connection.ExecuteAsync(updateQuery, userObj);

Though in these helper functions also, you need to pass the name of the fields you want to insert or update but at least you have full control over the query and can also include different WHERE clauses as and when required.

Through this helper functions, you will save the following lines of code:

For Insert Query:

 $ "INSERT INTO UserDetails (UserName,City) VALUES (@UserName,@City) RETURNING UserId";

For Update Query:

$"UPDATE UserDetails SET UserName=@UserName, City=@City WHERE UserId=@UserId";

There seems to be a difference of few lines of code, but when it comes to performing insert or update operation with a table having more than 10 fields, one can feel the difference.

You can use the nameof operator to pass the field name in the function to avoid typos

Instead of:

List < string > columns = new List < string > {
 "UserName",
 "City"
}

You can write:

List < string > columns = new List < string > {
nameof(UserEntity.UserName),
nameof(UserEntity.City),
}
Vansickle answered 6/7, 2020 at 5:48 Comment(0)
J
5

Stored procedure + Dapper method or SQL insert statement + Dapper do the work, but it do not perfectly fulfill the concept of ORM which dynamic mapping data model with SQL table column, because if using one of the above 2 approaches, you still need hard code some column name value in your stored procedure parameter or SQL insert statement.

To solve the concern of minimize code modification, you can use Dapper.Contrib to support SQL insert, here is the official guide and below was the sample setup and code

Step 1

Set up your class model in C#, by using Dapper.Contrib.Extensions : [Table] attribute will point to the desired table name in your SQL box, [ExplicitKey] attribute will tell Dapper this model properties is a primary key in your SQL table.

[Table("MySQLTableName")]
public class UserModel
{
   [ExplicitKey]
   public string UserId { get; set; }
   public string Name { get; set; }
   public string Sex { get; set; }
}

Step 2

Setup you SQL database/table something like this:

enter image description here

Step 3

Now build your C# code as something like below, you need to use these namespaces:

using Dapper.Contrib.Extensions;
using System.Data;

Code:

string connectionString =
    "Server=localhost;Database=SampleSQL_DB;Integrated Security=True";

UserModel user1 = new UserModel { UserId = "user0000001", 
                                     Name = "Jack", Sex = "Male" };
UserModel user2 = new UserModel { UserId = "user0000002", 
                                     Name = "Marry", Sex = "female" };
UserModel user3 = new UserModel { UserId = "user0000003", 
                                     Name = "Joe", Sex = "male" };

List<UserModel> LstUsers = new List<UserModel>();
LstUsers.Add(user2); LstUsers.Add(user3);

try
{
   using (IDbConnection connection = 
          new System.Data.SqlClient.SqlConnection(connectionString))
   {
      connection.Open();

      using (var trans = connection.BeginTransaction())
      {
        try
        {
           //  insert single record with custom data model
           connection.Insert(user1, transaction: trans);

           // insert multiple records with List<Type>
           connection.Insert(LstUsers, transaction: trans);

           // Only save to SQL database if all required SQL 
           // operations completed successfully 
           trans.Commit();
        }
        catch (Exception e)
        {
           // If one of the SQL operation fail , 
           // roll back the whole transaction
           trans.Rollback();
        }
     }
  }
}
catch (Exception e) { }
Jaunty answered 17/11, 2021 at 8:33 Comment(0)
S
1

You can try this:

 string sql = "UPDATE Customer SET City = @City WHERE CustomerId = @CustomerId";             
 conn.Execute(sql, customerEntity);
Selfseeker answered 25/9, 2018 at 16:57 Comment(0)
P
0

Here is a simple example with Repository Pattern :

public interface IUserRepository
{
    Task<bool> CreateUser(User user);
    Task<bool> UpdateUser(User user);
}

And in UserRepository :

public class UserRepository: IUserRepository
    {
        private readonly IConfiguration _configuration;

        public UserRepository(IConfiguration configuration)
        {
            _configuration = configuration;
        }

        public async Task<bool> CreateUser(User user)
        {
            using var connection = new NpgsqlConnection(_configuration.GetValue<string>("DatabaseSettings:ConnectionString"));

            var affected =
                await connection.ExecuteAsync
                    ("INSERT INTO User (Name, Email, Mobile) VALUES (@Name, @Email, @Mobile)",
                            new { Name= user.Name, Email= user.Email, Mobile = user.Mobile});

            if (affected == 0)
                return false;

            return true;
        }

        public async Task<bool> UpdateUser(User user)
        {
            using var connection = new NpgsqlConnection(_configuration.GetValue<string>("DatabaseSettings:ConnectionString"));

            var affected = await connection.ExecuteAsync
                    ("UPDATE User SET Name=@Name, Email= @Email, Mobile = @Mobile WHERE Id = @Id",
                            new { Name= user.Name, Email= user.Email, Mobile  = user.Mobile , Id = user.Id });

            if (affected == 0)
                return false;

            return true;
        }
    }

Note : NpgsqlConnection used for getting the ConnectionString of PostgreSQL database

Participation answered 5/10, 2021 at 15:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.