如何使用 Dapper.NET 将 C# 列表插入数据库
Posted
技术标签:
【中文标题】如何使用 Dapper.NET 将 C# 列表插入数据库【英文标题】:How to insert a C# List to database using Dapper.NET 【发布时间】:2013-06-13 14:02:52 【问题描述】:使用dapper,如何将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 获取数据,但这是我第一次尝试使用 insert query。
我尝试了下面的代码,使用链接到查询的Exceute
,但遇到了循环;我认为使用 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
。
【问题讨论】:
【参考方案1】:你必须做一些不同的事情。在 Dapper 中,它匹配与 SQL 参数相同的约定 AKA 属性或字段名称。所以,假设你有一个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);
【讨论】:
其实鲜为人知的事实:dapper 会为你迭代;中间的可以是:connection.Execute("INSERT INTO PROCESS_LOGS VALUES (@A, @B)", processList);
@DavidH 我认为不需要循环?
我的上帝,马克,你永远不会停下来让我吃惊。现在我必须去重新检查我在过去 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)
)。
@Mackan dapper 不会,但是 LINQ:使用 listOfChildren.Select(childId => new A = parentId, B = childId)
作为参数【参考方案2】:
我相信批量插入比迭代列表并一一插入要好。
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://***.com/a/12609410/1136277
【讨论】:
我不认为这是批量插入。单独插入已完成。请参阅您提供的链接中的 cmets。【参考方案3】:使用 Dapper.Contrib https://dapper-tutorial.net/insert#example---insert-single !您可以毫不费力地在 db 中插入对象列表。
【讨论】:
以上是关于如何使用 Dapper.NET 将 C# 列表插入数据库的主要内容,如果未能解决你的问题,请参考以下文章
dapper.net,如何刷新 ConcurrentDictionary?
使用Dapper.NET异步API时如何尊重CommandTimeout