<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های علیرضا علی‌مردان</title>
        <link>https://virgool.io/feed/@alimardan</link>
        <description>علیرضا علیمردان-یک برنامه‌نویس.علاقه‌مند به حوزه فن‌آوری اطلاعات،هوافضا و ریاضیات.</description>
        <language>fa</language>
        <pubDate>2026-06-16 21:24:17</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/2389437/avatar/avatar.png?height=120&amp;width=120</url>
            <title>علیرضا علی‌مردان</title>
            <link>https://virgool.io/@alimardan</link>
        </image>

                    <item>
                <title>آشنایی با Sqlkata و کاربرد آن</title>
                <link>https://virgool.io/@alimardan/%D8%A2%D8%B4%D9%86%D8%A7%DB%8C%DB%8C-%D8%A8%D8%A7-sqlkata-%D9%88-%DA%A9%D8%A7%D8%B1%D8%A8%D8%B1%D8%AF-%D8%A2%D9%86-npzvabquc0ez</link>
                <description>همه با کم و بیش با زبان Sql و پایگاه داده‌هایی که بر مبنای Structured Query Language آشنا هستیم، در واقع این زبان یک ابزار استاندارد برای استفاده از پایگاه‌ داده‌های relational است.امروزه معروفترین پایگاه داده‌هایی که ساختار relational دارند و زبان Sql را پشتیبانی میکنند(البته هرکدام با کمی تفاوت و شخصی سازی) میتوان به Microsoft SQL Server, MySQL, Oracel اشاره نمود.همانطور که قبلا گفته شد، گرچه تمام این پایگاه داده‌ها بر مبنای زبان SQL هستند ولی جزئیات دستورات و ساختار گاها متفاوت است. به عنوان مثال نحوه صفحه بندی داده‌ها در Microsoft SQL Server نسخه 2012 به بعد به شکل زیر است:SELECT * FROM [Posts] ORDER BY (SELECT 0) OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLYاست و در نسخه‌های قدیمی‌تر از 2012 به این شکل:SELECT * FROM (
    SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS [row_num] FROM [Posts]
) WHERE [row_num] BETWEEN 21 AND 30و سرانجام در MySql به این شکل:SELECT * FROM `Posts` LIMIT 10 OFFSET 20همانطور که می‌بینید، هریک از این پایگاه داده درحالیکه از SQL پشتیبانی میکنند به شکلی متفاوت ساختار دستوری را پیاده کرده‌اند.گرچه امروزه اکثر برنامه‌نویسان از ابزارهای ORM برای ارتباط با پایگاه داده استفاده میکنند، که معروفترین آنها Entity Framework و NHibernate هستند. اما هنوز در برخی سناریوها نیاز به استفاده از Query مستقیم است بخصوص زمانیکه بحث کارایی، سرعت و امنیت در میان باشد.مهمترین هدف Sqlkata نیز بر همین اساس استوار شده، یعنی ایجاد یک لایه نزدیک به زبان برنامه نویسی C# و تولید Query بنا به نیاز و متناسب با پایگاه داده هدف. در واقع Sqlkata ابزاری برای تولید کوئری است.این ابزار خاص زبان C# توسعه یافته و کد آن در گیت  بصورت Open source موجود است. دستورات مربوط به این ابزار تاحدودی شبیه به Linq و اما بیشتر شبیه به خود Sql هستند. این ابزار علاوه بر تولید کوئری متناسب با پایگاه داده موردنظر امکان اجرای دستورات جهت درج، ویرایش، حذف و نیز انتخاب را دارد. شما میتوانید نتیجه اجرای یک دستور را به اشیاء تعریف شده در قالب یک &lt;IEnumerable&lt;dynamic تبدیل کنید.همانطور که میدانید IEnumerable یک رابط Generic است و در صورت نیاز شما میتوانید رابط/کلاس هدف جهت تبدیل را مستقیم معرفی کنید مثل:IEnumerable&lt;dynamic&gt; users = db.Query(&amp;quotUsers&amp;quot).Get();به مرور پستهای بیشتری در مورد Sqlkata خواهم نوشت و به اشتراک خواهم گذاشت.به امید موفقیت شما!</description>
                <category>علیرضا علی‌مردان</category>
                <author>علیرضا علی‌مردان</author>
                <pubDate>Sat, 15 Apr 2023 23:50:39 +0330</pubDate>
            </item>
                    <item>
                <title>تفاوت IEnumerable با IQueryable</title>
                <link>https://virgool.io/@alimardan/%D8%AA%D9%81%D8%A7%D9%88%D8%AA-ienumerable-%D8%A8%D8%A7-iqueryable-fpl7ya28w8bc</link>
                <description>قطعا زمانهایی برای شما هم پیش آماده که بین استفاده این دو گزینه گیج شده باشید و بخواهید تفاوت بین آنها را بدانید. بهترین راه برای تصمیم گیری این است که بدانید هریک از این دو گزینه چه کاری انجام میدهند و برای چه سناریویی کارایی بهتری دارند.رابط (interface) که در فضای‌نام System.Collection است، متمرکز به جستجو در داده‌های in-Memory است، درحالیکه IQueryable برای واکشی داده‌ها از منابع خارج از حافظه(out-Memory) مثل پایگاه‌داده، فایلها، سرویسها و ... است.در سناریو مربوط به واکشی داده از پایگاه داده‌ای مثل sql بهترین توضیح میتواند عکس زیر باشد.واکشی داده با استفاده از IEnumerableهمانطور که مشاهده میکنید در کد فرضی :EmpEntities ent = new EmpEntities();
IEnumerable&lt;Employee&gt; emp = ent.Employees; 
IEnumerable&lt;Employee&gt; temp = emp.Where(x =&gt; x.Empid == 2).ToList&lt;Employee&gt;();ابتدا تمام داده‌ها از پایگاه داده واکشی شده، به حافظه منتقل می‌شوند و در آنجا فیلتر اعمال می‌گردد. اما اگر شما از IQueryable استفاده کنید با حالتی شبیه به شکل زیر مواجه خواهید بود:واکشی داده با استفاده از Queryableنمونه کد برای حالت فوق:EmpEntities ent = new EmpEntities();
IQueryable&lt;Employee&gt; emp = ent.Employees;
IQueryable&lt;Employee&gt; temp =  emp.Where(x =&gt; x.Empid == 2).ToList&lt;Employee&gt;();در این حالت، ابتدا در پایگاه داده فیلتر اعمل می‌شود و سپس داده فیلتر شده به حافظه سمت کلاینت منتقل می‌شود.بطور خلاصه میتوان گفت، در سناریو که داده کم حجم است یا داده در دفعات زیاد و گزینه‌های فیلتر متفاوت قرار بر ارجاع به داده باشد، قطعا استفاده از IEnumerable برای کش کردن و نیز جستجو با سرعت بالاتر(در اکثر اوقاع حافظه RAM سمت کلاینت سرعت بالاتری از جستجو در سرور دارند) بهتر است اما در حالتی که داده حجم زیادی دارد می‌توان با ابتدا داده را سمت سرور فیلتر و نتیجه نهایی با حجم کم را سمت کلاینت فرستاد.استفاده از IEnumerable سربار سمت سرور را کاهش میدهد اما بخاطر انتقال تمام داده به کلاینت پهنای باند بیشتری نیاز دارد و حافظه بیشتر از کلاینت را مشغول خواهد نمود.</description>
                <category>علیرضا علی‌مردان</category>
                <author>علیرضا علی‌مردان</author>
                <pubDate>Sat, 15 Apr 2023 01:07:23 +0330</pubDate>
            </item>
                    <item>
                <title>عملگرها ریاضی Generic در دات‌نت .NET</title>
                <link>https://virgool.io/@alimardan/%D8%B9%D9%85%D9%84%DA%AF%D8%B1%D9%87%D8%A7-%D8%B1%DB%8C%D8%A7%D8%B6%DB%8C-generic-%D8%AF%D8%B1-%D8%AF%D8%A7%D8%AA-%D9%86%D8%AA-net-v2ccgcz9wjfm</link>
                <description>عملگرها ریاضی Generic در دات‌نت ابتدا در دات‌نت نسخه 6 معرفی شدند و در ادامه در .NET 7 بسط و گسترش یافته‌اند.در واقع Generic Math با ترکیب توانایی Generic ها و خصیصه جدیدی بنام static virtuals in interfaces ایجاد شده اند تا به برنامه‌نویسان امکان استفاده از مزایای APIهای static، شامل عملگرها در کدهای عمومی (Generic) را بدهند. بدین شکل که با یک الگوسازی مجموعه‌ای از عملگرها با منطق یکسان را برای طیف گسترده‌ای از داده‌های سازگار فراهم آورند.خصیصه static virtual members in interfaces از دات‌نت 7 و سی‌شارپ 11 به بعد معرفی شده است.به این ترتیب زمانیکه شما یک عملگر با منطق و رویه کاری مشابه داشته باشید می‌توانید به این صورت اقدام به تعریف الگویی براساس Generic نمایید و نیاز به پیاده‌سازی جداگانه برای انواع داده مختلف نیست.static T Add&lt;T&gt;(T left, T right) where T : INumber&lt;T&gt; =&gt; left + right;هم اکنون کتابخانه‌های دات‌نت به عنوان بخشی از LINQ اقدام به ساده سازی توابع Enumerable.Max و Enumerable.Min نموده‌اند.(https://github.com/dotnet/runtime/pull/68183)خلاصه کلام اینکه با پشتیبانی یک API از یک Interface مثل &lt;INumber&lt;T هر نوعی که این واسط را پیاده سازی کند شامل پشتیبانی آن API خواهد بود.یک مثال می‌تواند در مورد محاسبه Deviation (انحراف معیار) که برمبنای استفاده از دو تابع Sum و Average کار میکند باشد.(اساساً برای تعیین میزان پراکندگی مجموعه ای از مقادیر استفاده می شود.)تابع اول Sum است، که مجموعه‌ای از اعداد را با هم جمع می‌کند. این تابع ورودی از نوع &lt;IEnumerable&lt;T دارد که در آن T باید واسط (interface) &lt;Inumber&lt;T را پیاده‌سازی کرده باشد.این متد خروجی از نوع TResult خواهد داشت، که نوع خروجی نیز به نوبه خود اقدام به پیاده‌سازی &lt;INumber&lt;TResult نموده است. در اینجا بخاطر وجود دو نوع پارامتر Generic امکان بازگرداندن خروجی با نوع متفاوت از ورودی خواهد بود. مثلا تابع می‌تواند به شکل &lt;Sum&lt;int, long تعریف شود که در آن یک آرایه از نوع int دارد و خروجی از نوع long خواهد بود.در این مثال TResult.Zero به معنی مقدار 0 به عنوان خروجی و تابع TResult.CreateChecked برای ایجاد خطای  OverflowException  در فرآیند تبدیل مقدار T به TResult در صورتیکه مقدار کمتر یا بیشتر از ظرفیت نوع خروجی (TResult) باشد. مثلا اگر &lt;Sum&lt;int,byte را در نظر بگیریم، در صورتیکه مقدار خروجی بیشتر از 255 باشد با خطای OverflowException مواجه خواهیم شد.کد تابع Sum بصورت Generic Mathتابع بعدی Average است، این تابع مجموعه‌از اعداد را با هم جمع و سپس به تعداد آنها تقسیم خواهد نمود.کد تابع Average بصورت Generic Mathدر نهایت هم تابع StandardDeviation را خواهیم داشت، این تابع با استفاده از دو تابع قبلی اقدام به محاسبه انحراف از معیار مجموع اعداد ورودی مینماید. این تابع یک قید (constraint) جدید بنام IFloatingPointIeee754 را به عنوان رابط (interface) نوع خروجی معرفی می‌کند.اما IFloatingPointIeee754 چیست؟ این interface اعلام می‌دارد که نوع باید استاندارد IEEE 754 در مورد تعداد اعشار رعایت کند که در واقع اشاره به انواع System.Double (double) و System.Single(float) در دات‌نت دارد.در اینجا ما با یک API جدید بنام CreateSaturating روبرو هستیم که وظیفه آن تبدیل بین انواع و مدیریت سرریز است. این تابع بخصوص در مورد انواع اعشار شناور با توجه به بازه گسترده ذخیره‌سازی آنها، بیانگر رفتار تبدیل مقادیر است و تضمین کننده ذخیره درست عدد و پیشگیری از خطای سرریز است(این رفتار وظیفه ذاتی نوع داده اعشاری است). به مانند رفتار byte.CreateSaturating که 1- را به 0 تبدیل میکند زیرا امکان ذخیره مقادیر کمتر صفر در نوع داده byte نیست یا تبدیل مقدار 256 به 255 با توجه به سقف حداکثری نوع byte.دیگر API نیز Sqrt است و در واقع همان عملیات Math.Sqrt یا MathF.Sqrt را پیاده سازی میکند و ریشه دوم عدد را محاسبه میکند.تابع نهایی محاسبه انحراف از معیار با استفاده از Generic Mathاز این پس تمام انوع داده‌هایی که رابط (interface)های مورد نیاز را پیاده‌سازی کرده باشند امکان استفاده از این توابع را خواهند داشت(البته در دات‌نت7 و بالاتر).</description>
                <category>علیرضا علی‌مردان</category>
                <author>علیرضا علی‌مردان</author>
                <pubDate>Fri, 14 Apr 2023 23:29:29 +0330</pubDate>
            </item>
                    <item>
                <title>دانت 7 و Native AOT</title>
                <link>https://virgool.io/@alimardan/%D8%AF%D8%A7%D9%86%D8%AA-7-%D9%88-native-aot-tgmtolprjbhz</link>
                <description>یکی از ویژگیهای که در دانت نسخه 7 (.NET 7) روی آن مانور زیادی شده بحث مربوط به Native AOT.کلمه AOT مخفف ahead-of-time است و به این اشاره دارد که کدهای شما پیشاپش و با توجه به شناخت شما از سیستم هدف جهت اجرا توسط کامپایلر (بدون استفاده از JIT) مستقیما به کدهای بومی خاص آن سیستم عامل کامپایل شده است.در واقع پیش‌دستی کردن در کامپایل IL به کدهای بومی سیستم هدف باعث می‌شود برنامه برای اجرا دیگر نیاز به Just-In-Time(JIT) در زمان اجرا نداشته باشد.این ویژگی به کاهش حافظه مورد نیاز از یک سو و افزایش سرعت آماده سازی برنامه از سوی دیگر منجر خواهد شد. به همین خاطر در سناریوهایی که نیاز به ایجاد نمونه های زیادی از یک برنامه وجود دارد (مثل فضاهای ابری) و پردازش های توزیع شده گزینه بسیار مناسبی است.اما خب استفاده از این ویژگی مستلزم شناسایی دقیق محیط اجرا مثل Linux x64 یا Windows x64 است، دقیقا مانند رفتاری که برای برنامه های self-contained app می‌شود.چرخه اجرای معمول با استفاده از JITاستفاده از این ویژگی در کنار مزایای خود دارای محدودیتهایی است که شامل موارد زیر است:عدم امکان بارگزاری داینامیک در زمان اجرا مثل Assembly.LoadFileعدم امکان ایجاد کد در زمان اجرا مثل System.Reflection.Emitعدم دسترسی به C++/CLIمحدودیتهای اعمال شده مربوط به trimmingافزایش حجم نسخه نهایی در زمان انتشار بخاطر نیاز به دربرداشتن کلیه کتابخانه‌مورد استفاده.</description>
                <category>علیرضا علی‌مردان</category>
                <author>علیرضا علی‌مردان</author>
                <pubDate>Thu, 13 Apr 2023 03:33:54 +0330</pubDate>
            </item>
            </channel>
</rss>