زمانی که از Dapper برای خواندن اطلاعات, افزودن اطلاعات و ... استفاده میکنید, در کتابخانه Dapper کوئری نوشته شده شما در یک ConcurrentDictionary نگهداری میشود که اگر مجددا همان کوئری اجرا شد, پروسس لازم برای اجرای کوئری مجدد اجرا نشود. حداکثر کوئری نگهداری شده در این ConcurrentDictionary برابر با 1000 رکورد می باشد و اگر بیشتر از آن وارد ConcurrentDictionary شود ConcurrentDictionary ریست میشود و تمامی Key ها پاک میشوند (Github). Key ایجاد شده برای این ConcurrentDictionary برابر است با کوئری نوشته شده شما. برای مثال در کد زیر به ازای هربار اجرا شدن حلقه یک Key جدید در ConcurrentDictionary اضافه میشود:
const string connectionString = "Data Source=.; Initial Catalog=DapperTest; Integrated Security=True;";
static async Task Main()
{
using var connection = new SqlConnection(connectionString);
await RunWithoutParameter(connection);
}
private static async Task RunWithoutParameter(SqlConnection connection)
{
for (int i = 0; i < 1000; i++)
{
string username = Guid.NewGuid().ToString();
var query = $@"SELECT Id, Username, Email FROM Users With(NOLOCK)
Where Username = '{username}'";
var result = await connection.QueryAsync<UserInformation>(query);
}
}
در کد بالا به ازای هربار اجرا شدن حلقه یک Key جدید در ConcurrentDictionary اضافه میشود که هیچ مزیتی ندارد. فقط تعداد Key ها در ConcurrentDictionary اضافه میشوند. اما اگر مقدار متغییر username که به SQL ارسال میشود, به صورت پارامتر ارسال کنیم, فقط یک کوئری به ازای 1000 بار اجرای حلقه ایجاد میشود.
static async Task Main()
{
using var connection = new SqlConnection(connectionString);
await RunWithParameter(connection);
}
private static async Task RunWithParameter(SqlConnection connection)
{
for (int i = 0; i < 1000; i++)
{
string username = Guid.NewGuid().ToString();
var query = $@"SELECT Id, Username, Email FROM Users With(NOLOCK)
Where Username = @username";
var result = await connection.QueryAsync<UserInformation>(query, new { username });
}
}
اگر به Key های ایجاد شده در Dapper نگاه کنید یک Key به صورت زیر ایجاد شده است:
SELECT Id, Username, Email FROM Users With(NOLOCK)
Where Username = @username
اما اگر کوئری اول را اجرا کنید به ازای هربار اجرا یک Key به صورت زیر در ConcurrentDictionary اضافه میشود:
SELECT Id, Username, Email FROM Users With(NOLOCK)
Where Username = '0fdfff64-41d5-4321-aebd-8637ae2d3314'
SELECT Id, Username, Email FROM Users With(NOLOCK)
Where Username = '2718efce-d352-4ea9-b25b-9ce5050828b4'
SELECT Id, Username, Email FROM Users With(NOLOCK)
Where Username = '7149faa0-4f77-4d17-9b34-a420efcb4c51'
SELECT Id, Username, Email FROM Users With(NOLOCK)
Where Username = 'f8f4426a-e7c2-49c6-a207-5fff3f656a4e'
SELECT Id, Username, Email FROM Users With(NOLOCK)
Where Username = 'edbddc29-690c-423d-9a8c-bf934eaf7bcb'
SELECT Id, Username, Email FROM Users With(NOLOCK)
Where Username = 'ee9bf534-7f35-4d1f-b172-29458666b178'
بنابراین بهتر است همیشه از پارامتر برای ارسال متغییرها به SQL با استفاده از Dapper استفاده کنیم.
;)
Powered by Froala Editor