نظرات مطالب
استفاده از پروایدر SQLite در Entity Framework 7
یک نکته‌ی تکمیلی: اگر از بانک اطلاعاتی SQLite استفاده می‌کنید، بهتر است از API غیرهمزمان EF-Core، برای کار با آن استفاده نکنید!

توصیه عمومی جهت کار با بانک‌های اطلاعاتی، استفاده از API غیرهمزمان (async) آن‌ها برای انجام هر نوع عملیات I/O مرتبط با آن‌هاست؛ اما ... SQLite، هیچگونه I/O شبکه‌ای را به همراه ندارد و همچنین پشت صحنه‌ی پیاده سازی آن نیز مبتنی بر استفاده‌ی از متدهای متداول همزمان است. برای مثال SQLite جهت پیاده سازی حالت WAL آن، از تابع همزمان ()fsync استفاده می‌کند و عملا Asynchronous I/O ای در اینجا رخ نمی‌دهد. یکی از مهم‌ترین مزایای فعال بودن حالت WAL، امکان کار چند ریسمانی با بانک اطلاعاتی SQLite، بدون دریافت خطای «Error: database is locked» است که سبب می‌شود بتوان از این بانک اطلاعاتی، بدون بروز هیچ مشکلی، در برنامه‌های وب نیز استفاده کرد.
یعنی API async آن (منظور API ای که توسط EF-Core ارائه می‌شود)، صرفا یک شبه محصور کننده‌ی blocking API همزمان آن است (یک async تقلبی!) و بیشتر سبب بروز یک سربار ناخواسته می‌شود؛ تا اینکه بهبود کارآیی خاصی را به همراه داشته باشد. به همین جهت بهتر است حین کار با بانک اطلاعاتی SQLite، از همان synchronous API معمولی و متداول آن استفاده شود.
نظرات مطالب
مشکل همزمانی خواندن و به روز رسانی اطلاعات در برنامه‌های وب
- در این مثال در حالت پیش‌فرض READ COMMITTED isolation level تراکنش، هرچند وجود UPDLOCK ضروری است، اما کافی نیست و باید به همراه HOLDLOCK هم باشد، تا اثر آن تا پایان تراکنش باقی بماند تا هم select و هم update، در حالت‌های پردازش موازی، هر دو تحت کنترل قرار گیرند.
- روش اضافه کردن خودکار این hintها به تمام کوئری‌های EF، با استفاده از Interceptorها، بدون نیاز به SQL نویسی مستقیم و عدم استفاده از LINQ: « بهبود عملکرد SQL Server Locks در سیستم‌های با تعداد تراکنش بالا در Entity Framework »
نظرات مطالب
بازنویسی سطح دوم کش برای Entity framework 6
این روش رو استفاده کرده بودم. مشکلی که وجود داره اینه که بعد تغییر مقدار متغیر و ذخیره در دیتابیس ، تغییرات در کش اعمال نمیشه یعنی تابع load همچنان مقدار قبلی متغیر که در کش موجود هست رو بر می‌گردونه.
نظرات اشتراک‌ها
رایگان شدن بیش از ۷۰۰۰ دوره سایت Pluralsight
برنامه‌ای برای دریافت لینک‌های دانلود دوره‌های پلورال‌سایت

حدودا 23 روز دیگر تا پایان دسترسی رایگان به پلورال‌سایت باقی است. به همین جهت، برنامه‌ای تهیه شد که توسط آن می‌توانید لینک‌های مستقیم دریافت فایل‌های دوره‌های پلورال‌سایت را یافته و توسط دانلودمنیجر خود، آن‌ها را دریافت کنید: PluralsightLinks.7z

روش استفاده:
- سورس کامل برنامه قرار داده شده‌است و برای اجرا، نیاز به NET Core 3.1. را دارد.
- فایل appsettings.json آن‌را باز کنید. سپس در آن Username و Password ورود به سایت پلورال‌سایت خود را وارد کنید.
- سپس آرایه‌ی CoursesToCheck را با فرمتی که مشاهده می‌کنید، بر اساس لینک‌های اول صفحات دوره‌های مورد علاقه‌ی خود تکمیل کنید.

و در آخر با کلیک بر روی فایل dotnet_run.bat، می‌توانید برنامه را اجرا کرده و نتایج نهایی را در پوشه‌ی Output تشکیل شده، مشاهده کنید. این نتایج به صورت فایل‌های txt ذخیره می‌شوند که به سادگی قابلیت import در دانلودمنیجرها را دارند.

دو نکته‌ی مهم:
- لینک‌های یافت شده، مدت‌دار هستند. بنابراین سریعتر نسبت به دریافت آن‌ها اقدام کنید! بدیهی است در صورت منقضی شدن لینک‌ها، باید مجددا لینک‌های جدید را با اجرای مجدد برنامه، دریافت کنید.
- اگر با IP ایران می‌خواهید از این برنامه استفاده کنید، بلافاصله پس از لاگین، خطای 403 و عدم دسترسی را مشاهده خواهید کرد. برای رفع این مشکل، می‌توانید DNS خود را به «شکن» تنظیم کنید؛ یعنی تنظیم DNS به 178.22.122.100 به صورت زیر:


پس از این تغییر، چون IP قابل مشاهده‌ی سیستم شما توسط سایت پلورال‌سایت، تغییر می‌کند، مرحله‌ی لاگین و کار با سایت را بدون مشکل طی خواهید کرد.

به روز رسانی‌ها:
- برنامه را کمی تغییر دادم تا خودش فایل‌ها را هم یکی یکی دریافت کند؛ آهسته و پیوسته، به همراه ایجاد پوشه‌ها، به ازای هر ماژول دوره و نام‌گذاری صحیح فایل‌های ویدیوهای دریافتی: PluralsightLinks-V2.7z 
- امکان دریافت زیرنویس‌های هر ویدیو هم اضافه شد: PluralsightLinks-V5.7z  
نظرات مطالب
کار با کوکی‌ها در ASP.NET Core
یک نکته‌ی تکمیلی: ارتقاء به نگارش 3.1 و تغییر تنظیمات کوکی‌ها


مرورگر کروم، از نگارش 80 آن به بعد به همراه یک تغییر غیرسازگار با نگارش‌های قبلی آن است: از این پس تمام کوکی‌های آن در صورتیکه تنظیمات SameSite را نداشته باشند، به صورت SameSite=Lax تفسیر می‌شوند؛ که تغییر امنیتی فوق العاده‌ای است و سبب خواهد شد تا بسیاری از حملات مانند CSRF به طور کامل غیرعملی شوند. اما ... این مورد سبب از کار افتادن برنامه‌هایی خواهد شد که از سرویس‌هایی مانند IdentityServer استفاده می‌کنند. در یک چنین حالتی نیاز خواهید داشت برای رفع این مشکل، SameSite=None را تنظیم کنید.

اما SameSite چیست؟ تنظیم و خاصیت SameSite از سال 2016 به کوکی‌ها اضافه شد تا بتوان توسط آن در برابر حملات CSRF مقاومت کرد؛ مقادیر اولیه‌ی آن نیز Lax و Strict بودند. Lax به این معنا است که کوکی‌ها در حین مرور یک سایت، باید به صورت خودکار به سمت سرور همان سایت ارسال شوند؛ اما در حالت مرور سایت و هدایت از طریق سایت‌های دیگر به سایت ما، فقط درخواست‌های GET رسیده می‌توانند کوکی‌ها را نیز ارسال کنند. حالت Strict آن فقط کوکی‌های تنظیم شده‌ی درون یک سایت را معتبر شمرده و ارسال می‌کند. عدم تنظیم SameSite نیز مشکل خاصی را ایجاد نمی‌کرد. برای مثال اعمال اعتبارسنجی مبتنی بر OpenIdConnect مانند login/logout، نیاز دارند در طی یک درخواست POST، اطلاعاتی را به سایت خارجی درخواست کننده ارسال کنند. برای اینکه این عملیات به درستی صورت گیرد، می‌بایستی تنظیمات SameSite انجام نمی‌شد تا جابجایی کوکی‌ها بین دو دومین مختلف در حالت POST، بدون مشکل صورت می‌گرفت.
با تغییر جدید گوگل، حالت پیش‌فرض SameSite که اجباری نبود، به صورت اجباری به Lax تنظیم شده‌است؛ اما برای حالاتی مانند OpenIdConnect، مقدار None را نیز اضافه کرده‌است. به همین جهت این نوع برنامه‌ها اگر از تنظیم SameSite=None استفاده نکنند، دیگر نمی‌توانند کوکی‌های درخواست‌های POST را بین دومین‌های مختلف جابجا کنند.

مشکل مهم! مقدار None را فقط مرورگر کروم متوجه می‌شود و جزو استاندارد SameSite نیست! در این استاندارد اگر مقدار SameSite تنظیم شود و مرورگر نتواند آن‌را تشخیص دهد (مانند iOS 12)، مقدار Strict را به عنوان مقدار دریافتی تنظیم می‌کند! به همین جهت برنامه‌ی شما باید بر اساس نوع مرورگر تصمیم‌گیری کند که آیا باید SameSite را به خروجی اضافه کند یا خیر.

وضعیت دات نت در این مورد: با به روز رسانی‌های جدید دات نت 4.7.2 و همچنین NET Core 2.1.، مقدار جدید None توسط برنامه (در CookieOptions) قابل تنظیم خواهد بود که سبب تولید SameSite=None می‌شود. به علاوه در NET Core 3.1.،  مقدار SameSite.Unspecified را نیز می‌توان تنظیم کرد که سبب خواهد شد تا خاصیت SameSite اصلا تنظیم نشود (اصلا به درخواست اضافه نشود؛ تا مرورگرهایی که نمی‌توانند مقدار None را تفسیر کنند، به اشتباه آن‌را به Strict تنظیم نکنند).

به صورت خلاصه: اگر برنامه‌ی شما از OpenIdConnect و یا IdentityServer استفاده نمی‌کند، هیچ تنظیمی را تغییر ندهید! تنظیم پیش‌فرض SameSite=Lax گوگل سبب می‌شود تا عملا حملات CSRF دیگر بر روی سایت شما قابل اجرا نباشد. اما اگر از IdentityServer استفاده می‌کنید، این تنظیم پیش‌فرض، سبب از کار افتادن امکان ارسال کوکی‌های حالت POST، به سایت‌های خارجی می‌شود و برنامه و سیستم شما از کار خواهد افتاد.
نظرات مطالب
کوئری نویسی در EF Core - قسمت هشتم - کوئری‌های بازگشتی
راه حل بهتر!
کتابخانه‌ی « linq2db » از CTEها و recursive CTE پشتیبانی می‌کند. می‌توان این کتابخانه را توسط « linq2db.EntityFrameworkCore » با EF-Core یکی کرد. برای کار با آن ابتدا نیاز است بسته‌ی نیوگت آن‌را نصب کنید:
dotnet add package linq2db.EntityFrameworkCore
سپس در ابتدای برنامه یکبار آ‌ن‌را فعال کنید:
LinqToDB.EntityFrameworkCore.LinqToDBForEFTools.Initialize();
LinqToDB.Data.DataConnection.TurnTraceSwitchOn();
پس از آن به صورت زیر می‌توان از CTEها در کوئری‌های معمولی EF-Core استفاده کرد. برای مثال:

راه حل مثال 1 با استفاده از یک recursive CTE
می‌خواهیم لیست IDهای parent و childها را توسط یک recursive CTE تولید کنیم. به همین جهت ابتدا مدل معادل آن‌را تهیه می‌کنیم:
public class MemberHierarchyCTE
{
   public int ChildId { set; get; }
   public int? ParentId { set; get; }
}
سپس CTE زیر، این لیست را تهیه می‌کند:
var memberHierarchyCte =
                    context.CreateLinqToDbContext().GetCte<MemberHierarchyCTE>(memberHierarchy =>
                    {
                        return
                            (
                                from member in context.Members
                                select new MemberHierarchyCTE
                                {
                                    ChildId = member.MemId,
                                    ParentId = member.RecommendedBy
                                }
                            )
                            .Concat
                            (
                                from member in context.Members
                                from hierarchy in memberHierarchy
                                            .InnerJoin(hierarchy => member.MemId == hierarchy.ParentId)
                                select new MemberHierarchyCTE
                                {
                                    ChildId = hierarchy.ChildId,
                                    ParentId = member.RecommendedBy
                                }
                            );
                    });
که به این صورت ترجمه خواهد شد:
WITH [memberHierarchy] ([ChildId], [ParentId])
AS
(
    SELECT
        [member_1].[MemId],
        [member_1].[RecommendedBy]
    FROM
        [Members] [member_1]
    UNION ALL
    SELECT
        [hierarchy_1].[ChildId],
        [member_2].[RecommendedBy]
    FROM
        [Members] [member_2]
            INNER JOIN [memberHierarchy] [hierarchy_1] ON [member_2].[MemId] = [hierarchy_1].[ParentId]
)
و با کوئری گرفتن از آن برای مثال می‌توان لیست والدهای id=27 را تولید کرد (همان مثال 1):


راه حل مثال 2 با استفاده از یک recursive CTE 
و یا می‌توان لیست فرزندان id=1 را با کوئری گرفتن از این CTE تولید کرد (همان مثال 2):

نظرات مطالب
شروع به کار با EF Core 1.0 - قسمت 7 - بررسی رابطه‌ی One-to-Many
«بهبود عملکرد» با «بهبود کارآیی» یکی نیست. پیاده سازی سیستم change tracking در حالت کلی، بدون پیاده سازی مباحث AOP غیرممکن است. بهتر است دوره‌ی مرتبطی را در سایت در این مورد مرور کنید تا کلیات بحث تشکیل Proxyها بهتر مشخص شوند (و ... تشکیل پروکسی با روش‌های مختلفی و با الگوریتم‌های متفاوتی ممکن است و مهم نیست که dynamic proxy چندسکویی باشد یا خیر؛ این مورد نام یک الگوی طراحی شیء گرا است و نه یک کتابخانه‌ی خاص). هدف من از عنوان این مسایل، اشاره به کلیات زیرساخت پیاده سازی این مباحث هست.
برای نمونه زمانیکه مقدار خاصیت شیء واکشی شده‌ای از Context را تغییر می‌دهید و سپس SaveChanges را فراخوانی می‌کنید، در این بین یک پروکسی وجود دارد (یک لایه‌ی نامرئی و حائل بین شیء اصلی و تغییراتی که قرار است به آن اعمال شوند) که به تغییرات گوش فرا می‌دهد و در نهایت صرفا یک کوئری به روز رسانی آن فیلد خاص را تولید می‌کند و نه تمام فیلدهای دیگر را. این نوع مفاهیم کلی در اینجا مدنظر هستند. یک نمونه پیاده سازی کلی این مفهوم را در اینجا می‌توانید مشاهده کنید.
همچنین EF Core 2.1 به همراه بسته‌ی Microsoft.EntityFrameworkCore.Proxies است که پیاده سازی Lazy loading را میسر کرده‌است و از Castel.Core هم استفاده می‌کند (یا همان Castle DynamicProxy که در دوره «Aspect oriented programming» مورد بررسی قرار گرفته‌است).
مسیرراه‌ها
Blazor 5x

مبانی Blazor 

 احراز هویت و اعتبارسنجی کاربران Blazor Server

تهیه API مخصوص Blazor WASM
Blazor WASM 

احراز هویت و اعتبارسنجی کاربران Blazor WASM

توزیع برنامه 

مدیریت استثناءها

بررسی تغییرات Blazor 8x  

مطالب تکمیلی