117

Using , how can I insert a C# List to database. Previously without dapper I used the below code to insert the List values to database.

try
{                
    connection.Open();

    for (int i = 0; i < processList.Count; i++)
    {
        string processQuery = "INSERT INTO PROCESS_LOGS VALUES (@Id, @st_Time, @ed_Time, @td_Time)";
        command = new SqlCommand(processQuery, connection);
        command.Parameters.Add("Id", SqlDbType.Int).Value = processList[i].ID;
        command.Parameters.Add("st_Time", SqlDbType.DateTime).Value = processList[i].ST_TIME;
        command.Parameters.Add("ed_Time", SqlDbType.DateTime).Value = processList[i].ED_TIME;
        command.Parameters.Add("td_Time", SqlDbType.DateTime2).Value = processList[i].TD_TIME;
        dataReader.Close();
        dataReader = command.ExecuteReader();
    }

    connection.Close();
}
catch (SqlException ex)
{
    //--Handle Exception
}

I'm familiar with fetching the data using dapper but this is my first try using insert query.

I tried the below code, using Exceute linked to query but stuck up with looping; I think using dapper tool, there is no need for looping statement.

connection.Execute(processQuery ... );

EDIT:

class ProcessLog
    {
        public int ID { get; set; }
        public DateTime ST_TIME { get; set; }
        public DateTime ED_TIME { get; set; }
        public DateTime TD_TIME { get; set; }
        public string frequency { get; set; }
    }

Please advice on this. FYI: I'm using SQL Server 2008.

3 Answers 3

199

You'd have to do it a little differently. In Dapper, it matches on convention AKA property or field names being identical to SQL parameters. So, assuming you had a MyObject:

public class MyObject
{
    public int A { get; set; }

    public string B { get; set; }
}

And assuming processList = List<MyObject>, You'd want to do this

foreach (var item in processList)
{
    string processQuery = "INSERT INTO PROCESS_LOGS VALUES (@A, @B)";        
    connection.Execute(processQuery, item);
}

Note that the MyObject property names A and B match the SQL parameter names @A and @B.

If you don't want to rename objects, you can use anonymous types to do the mappings instead of concrete types:

foreach (var item in processList)
{
    string processQuery = "INSERT INTO PROCESS_LOGS VALUES (@A, @B)";        
    connection.Execute(processQuery, new { A = item.A, B = item.B });
}

EDIT:

Per Marc Gravell's comment, you can also have Dapper do the loop for you:

string processQuery = "INSERT INTO PROCESS_LOGS VALUES (@A, @B)";        
connection.Execute(processQuery, processList);
Sign up to request clarification or add additional context in comments.

27 Comments

Actually, little known fact: dapper will iterate for you; the middle one can be: connection.Execute("INSERT INTO PROCESS_LOGS VALUES (@A, @B)", processList);
My god, Marc you never stop to amaze me. Now I have to go and re-check all the code I've written in the past 10 days. (Since I decided to try this little gem)
Is there any way to simulate (@a1, @b1),(@a2, @b2) with Dapper? I'm trying to use SQL Server MERGE tble USING VALUES (('a1', 'b1'),('a2','b2')) AS foo(a,b) ON tble.a=foo.a WHEN MATCHED.... If not I'd rather iterate and run many statements than use a temp table, but Dapper creating my bracketed list would be very nice. Am doubtful as I think it is vendor specific. Although MySQL uses comma-delimited brackets to do multiple row inserts so perhaps it isn't? (INS INTO tbl (a,b) VALUES (a1,b1),(a2,b2)).
@Mackan dapper won't, but LINQ: use listOfChildren.Select(childId => new { A = parentId, B = childId}) as the arg
Anyone know if this does n round trips / execute to SQL server or does it neatly create 1 insert statement with multiple inserts? Surely the former will be very inefficient, specially if it's a long list?!
|
28

I believe the bulk insert is better than iterate the list and insert one by one.

SqlTransaction trans = connection.BeginTransaction();

connection.Execute(@"
insert PROCESS_LOGS(Id, st_Time, ed_Time, td_Time)
values(@Id, @st_Time, @ed_Time, @td_Time)", processList, transaction: trans);

trans.Commit();

Reference: https://stackoverflow.com/a/12609410/1136277

1 Comment

I don't believe that's a bulk insert. Individual inserts are done. See the comments in the link you provided.
2

Use Dapper.Contrib https://dapper-tutorial.net/insert#example---insert-single ! You can effortlessly insert list of objects in db.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.