زمانی که از 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

نظرات