【发布时间】:2017-04-23 17:42:52
【问题描述】:
我正在比较 Dapper 与 ADO.NET 和 Dapper 之间的实现时间。 最终,Dapper 往往比 ADO.NET 快,尽管第一次执行给定的 fetch 查询比 ADO.NET 慢。 一些结果表明 Dapper 比 ADO.NET 快一点(几乎所有结果都表明它具有可比性)
所以我认为我使用低效的方法将 SqlDataReader 的结果映射到对象。
这是我的代码
var sql = "SELECT * FROM Sales.SalesOrderHeader WHERE SalesOrderID = @Id";
var conn = new SqlConnection(ConnectionString);
var stopWatch = new Stopwatch();
try
{
conn.Open();
var sqlCmd = new SqlCommand(sql, conn);
for (var i = 0; i < keys.GetLength(0); i++)
{
for (var r = 0; r < keys.GetLength(1); r++)
{
stopWatch.Restart();
sqlCmd.Parameters.Clear();
sqlCmd.Parameters.AddWithValue("@Id", keys[i, r]);
var reader = await sqlCmd.ExecuteReaderAsync();
SalesOrderHeaderSQLserver salesOrderHeader = null;
while (await reader.ReadAsync())
{
salesOrderHeader = new SalesOrderHeaderSQLserver();
salesOrderHeader.SalesOrderId = (int)reader["SalesOrderId"];
salesOrderHeader.SalesOrderNumber = reader["SalesOrderNumber"] as string;
salesOrderHeader.AccountNumber = reader["AccountNumber"] as string;
salesOrderHeader.BillToAddressID = (int)reader["BillToAddressID"];
salesOrderHeader.TotalDue = (decimal)reader["TotalDue"];
salesOrderHeader.Comment = reader["Comment"] as string;
salesOrderHeader.DueDate = (DateTime)reader["DueDate"];
salesOrderHeader.CurrencyRateID = reader["CurrencyRateID"] as int?;
salesOrderHeader.CustomerID = (int)reader["CustomerID"];
salesOrderHeader.SalesPersonID = reader["SalesPersonID"] as int?;
salesOrderHeader.CreditCardApprovalCode = reader["CreditCardApprovalCode"] as string;
salesOrderHeader.ShipDate = reader["ShipDate"] as DateTime?;
salesOrderHeader.Freight = (decimal)reader["Freight"];
salesOrderHeader.ModifiedDate = (DateTime)reader["ModifiedDate"];
salesOrderHeader.OrderDate = (DateTime)reader["OrderDate"];
salesOrderHeader.TerritoryID = reader["TerritoryID"] as int?;
salesOrderHeader.CreditCardID = reader["CreditCardID"] as int?;
salesOrderHeader.OnlineOrderFlag = (bool)reader["OnlineOrderFlag"];
salesOrderHeader.PurchaseOrderNumber = reader["PurchaseOrderNumber"] as string;
salesOrderHeader.RevisionNumber = (byte)reader["RevisionNumber"];
salesOrderHeader.Rowguid = (Guid)reader["Rowguid"];
salesOrderHeader.ShipMethodID = (int)reader["ShipMethodID"];
salesOrderHeader.ShipToAddressID = (int)reader["ShipToAddressID"];
salesOrderHeader.Status = (byte)reader["Status"];
salesOrderHeader.SubTotal = (decimal)reader["SubTotal"];
salesOrderHeader.TaxAmt = (decimal)reader["TaxAmt"];
}
stopWatch.Stop();
reader.Close();
await PrintTestFindByPKReport(stopWatch.ElapsedMilliseconds, salesOrderHeader.SalesOrderId.ToString());
}
我使用as 关键字强制转换为可空列,对吗?
这是 Dapper 的代码。
using (var conn = new SqlConnection(ConnectionString))
{
conn.Open();
var stopWatch = new Stopwatch();
for (var i = 0; i < keys.GetLength(0); i++)
{
for (var r = 0; r < keys.GetLength(1); r++)
{
stopWatch.Restart();
var result = (await conn.QueryAsync<SalesOrderHeader>("SELECT * FROM Sales.SalesOrderHeader WHERE SalesOrderID = @Id", new { Id = keys[i, r] })).FirstOrDefault();
stopWatch.Stop();
await PrintTestFindByPKReport(stopWatch.ElapsedMilliseconds, result.ToString());
}
}
}
【问题讨论】:
-
如果你删除异步代码并进行比较会怎样?
-
“最终,Dapper 往往比 ADO.NET 更快” - 句子不计算; Dapper 位于 ADO.NET 之上;它不能比它消耗的东西快,而且ADO.NET 不提供您所追求的服务...您能更具体地说明您的意思吗?
-
在我看来,您的主要问题是您正在执行大量查询;您是否考虑过使用 INNER JOIN 或多个 SELECT (
.QueryMultiple) 在 一个 查询中执行所有操作,而不是执行多个查询? -
@MarcGravell 当我问这个问题时,我实际上忘记了 Dapper 位于 ADO.NET 之上。在我正确比较了所有测试结果之后(不仅仅是凝视它)。我必须承认我夸大了,一些结果表明 Dapper 更快的最高时间差是 9 毫秒,几乎所有的结果都表明它具有可比性,很少有表明 ADO.NET 更快。真的很抱歉浪费了您的时间。
标签: c# sql-server ado.net dapper