Esta es posiblemente la forma más rápida de consultar una gran cantidad de filas con Dapper utilizando una lista de ID. Te prometo que esto es más rápido que casi cualquier otra forma en que puedas pensar (con la posible excepción de usar un TVP como se indica en otra respuesta, y que no he probado, pero sospecho que puede ser más lento porque todavía tienes que llenar El TVP). Es planetas más rápido que Dapper usando IN
sintaxis y universos más rápido que Entity Framework fila por fila. Y es aún más rápido de lo que pasa continentes en una lista de VALUES
o UNION ALL SELECT
artículos. Se puede ampliar fácilmente para usar una clave de varias columnas, solo agregue las columnas adicionales a la DataTable
tabla temporal y las condiciones de unión.
public IReadOnlyCollection<Item> GetItemsByItemIds(IEnumerable<int> items) {
var itemList = new HashSet(items);
if (itemList.Count == 0) { return Enumerable.Empty<Item>().ToList().AsReadOnly(); }
var itemDataTable = new DataTable();
itemDataTable.Columns.Add("ItemId", typeof(int));
itemList.ForEach(itemid => itemDataTable.Rows.Add(itemid));
using (SqlConnection conn = GetConnection()) // however you get a connection
using (var transaction = conn.BeginTransaction()) {
conn.Execute(
"CREATE TABLE #Items (ItemId int NOT NULL PRIMARY KEY CLUSTERED);",
transaction: transaction
);
new SqlBulkCopy(conn, SqlBulkCopyOptions.Default, transaction) {
DestinationTableName = "#Items",
BulkCopyTimeout = 3600 // ridiculously large
}
.WriteToServer(itemDataTable);
var result = conn
.Query<Item>(@"
SELECT i.ItemId, i.ItemName
FROM #Items x INNER JOIN dbo.Items i ON x.ItemId = i.ItemId
DROP TABLE #Items;",
transaction: transaction,
commandTimeout: 3600
)
.ToList()
.AsReadOnly();
transaction.Rollback(); // Or commit if you like
return result;
}
}
Tenga en cuenta que necesita aprender un poco sobre las inserciones masivas. Hay opciones para disparar disparadores (el valor predeterminado es no), respetar las restricciones, bloquear la tabla, permitir inserciones concurrentes, etc.