如何使用Dapper.NET将C#列表插入数据库

113
使用 ,我如何将一个 C# List 插入到数据库中。之前没有 Dapper ,我使用以下代码将列表值插入到数据库中。
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
}

我熟悉使用dapper获取数据,但这是我第一次尝试使用插入查询

我尝试了下面的代码,使用Execute链接到查询,但卡在了循环中。我认为使用dapper工具,没有必要使用循环语句。

connection.Execute(processQuery ... );

编辑:

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; }
    }
请提供建议。 顺便说一下:我正在使用SQL Server 2008
3个回答

193

你需要做一些不同的事情。在Dapper中,它会根据惯例匹配属性或字段名称与SQL参数相同。因此,假设你有一个MyObject

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

    public string B { get; set; }
}

假设 processList = List<MyObject>,你想要这样做:

foreach (var item in processList)
{
    string processQuery = "INSERT INTO PROCESS_LOGS VALUES (@A, @B)";        
    connection.Execute(processQuery, item);
}
注意,MyObject属性的名称A和B与SQL参数名称@A和@B匹配。
如果您不想重命名对象,则可以使用匿名类型来执行映射而非具体类型:
foreach (var item in processList)
{
    string processQuery = "INSERT INTO PROCESS_LOGS VALUES (@A, @B)";        
    connection.Execute(processQuery, new { A = item.A, B = item.B });
}

编辑:

根据Marc Gravell的评论,你也可以让Dapper为你执行循环:

string processQuery = "INSERT INTO PROCESS_LOGS VALUES (@A, @B)";        
connection.Execute(processQuery, processList);

197
其实,鲜为人知的是:dapper可以为您迭代;中间那一行代码可以是:connection.Execute("INSERT INTO PROCESS_LOGS VALUES (@A, @B)", processList); - Marc Gravell
9
我的天啊,马克,你真是让我惊叹不已。现在我必须去重新检查我过去10天写的所有代码(自从我决定尝试这个小宝石)。 - Steve
1
@DavidH 这个方法很好用,我正在尝试按照Marc Gravell的建议来做。我的代码有些问题,我会尝试修复它并告诉你我的错误。谢谢。 - Praveen
10
有没有办法使用Dapper模拟(@a1, @b1),(@a2, @b2)这种格式?我想使用SQL Server的MERGE tble USING VALUES (('a1', 'b1'),('a2','b2')) AS foo(a,b) ON tble.a=foo.a WHEN MATCHED...语句。如果不行,我宁愿循环执行多条语句,也不想使用临时表,但如果Dapper可以创建我的带括号列表会非常好。我有点怀疑,因为我认为这是特定于供应商的。虽然MySQL使用逗号分隔的括号来进行多行插入操作,所以也许并不是这样?(INS INTO tbl (a,b) VALUES (a1,b1),(a2,b2)). - Chris
3
@Mackan dapper不会,但是可以使用listOfChildren.Select(childId => new { A = parentId, B = childId})作为参数的LINQ。 - Marc Gravell
显示剩余22条评论

26

我相信批量插入比逐个迭代列表插入更好。

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();

参考资料: https://dev59.com/42gv5IYBdhLWcg3wTvLL#12609410


6
我不相信那是批量插入。它是逐个插入的。请查看您提供的链接中的评论。 - Bob Horn

3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接