نرمافزار Continuous یک IDE سریع و قوی برای C# و F# است که مستقیما روی iPad و iPhone بدون نیاز به شبکه اجرا میشود. با استفاده از این IDE میتوانید اپها و بازیها را روی دیوایس خود کد بزنید و اجرا کنید. نحوه عمکرد Continuous به صورت تعاملی است به این معنا که دائما کد شما را اجرا میکند و میتوانید به محض تغییر در کد تاثیر آن را در اجرای برنامه ببینید.
اشتراکها
دوره 8 ساعته آموزش Blazor
اشتراکها
Rider 2021.1 منتشر شد
ASP.NET Core Identity از IdentityResult برای ساخت خروجی متدهایش استفاده میکند. نمونهی مشابه آن Result در DNT Framework هست و یا « پیاده سازی Option یا Maybe در #C ».
EF آقای بهروز راد
ASP.Net mvc آقای بهروز راد
ASP.Net mvc آقای بهروز راد
الگوهای طراحی در C# 5.0 آقای عمرانی
مطلبی را روز قبل نوشتم در مورد تعیین اعتبار یک کوئری. این مورد از آنجایی حائز اهمیت میشود که برای مثال تغییری در ساختار یکی از جداول حاصل شود. اکنون میخواهیم بررسی کنیم آیا سیستم از کار افتاده یا نه!؟
شما میتوانید نام یک فیلد را تغییر دهید (حتی اگر این فیلد در یک رویه ذخیره شده استفاده شده باشد) و هیچ خطایی هم نخواهید گرفت و این منشاء دردسرهای زیادی خواهد بود.
در حالت استفاده از SET NOEXEC ON ، کوئری مورد نظر فقط کامپایل میشود و همچنین از لحاظ نحوی بررسی خواهد شد، اما این کافی نیست.
مثال زیر را در نظر بگیرید:
Create PROCEDURE Test1
AS
SELECT * FROM tblPIDs1
این کوئری قابل اجرا است. دکمهی F5 را فشار دهید، بلافاصله رویه ذخیره شدهی Test1 برای شما ایجاد خواهد شد.
سپس کوئری زیر را اجرا کنید:
USE testdb
SET NOEXEC ON;
exec test1 ;
SET NOEXEC OFF;
Command(s) completed successfully
ایرادی هم وارد نیست چون فقط عملیات parsing و compile صورت گرفته و نه اجرای واقعی رویه ذخیره شده. اینجا از لحاظ دستوری مشکلی وجود ندارد.
در این نوع موارد میتوان از SET FMTONLY ON استفاده کرد. این مورد اجرای غیر واقعی یک کوئری را سبب میشود (تاثیری روی دیتابیس موجود نخواهد داشت، برای مثال اگر در رویه ذخیره شما عبارت insert وجود داشت، دیتایی insert نخواهد شد) و تنها متادیتای حاصل را بازگشت میدهد. مثلا نام ستونهای یک کوئری را و همچنین در این حین اگر خطایی رخ داده باشد، آنرا نیز ارائه خواهد داد.
USE testdb
SET FMTONLY ON;
exec test1 ;
SET FMTONLY OFF;
Msg 208, Level 16, State 1, Procedure test1, Line 3
Invalid object name 'tblPIDs1'.
USE testdb;
SET NOCOUNT ON;
DECLARE @name NVARCHAR(MAX),
@sql NVARCHAR(MAX),
@type CHAR(2), -- object type
@type_desc NVARCHAR(60), -- object type description
@params NVARCHAR(MAX) -- parameters
DECLARE @tblInvalid TABLE (
-- invalid objects
[type_desc] NVARCHAR(60),
[name] NVARCHAR(MAX),
[error_number] INT,
[error_message] NVARCHAR(MAX),
[type] CHAR(2)
);
DECLARE testSPs CURSOR FAST_FORWARD
FOR
SELECT [name] = OBJECT_NAME(SM.[object_id]),
[type] = SO.[type],
SO.[type_desc],
[params] = (
SELECT (
SELECT CONVERT(
XML,
(
SELECT STUFF(
(
SELECT ', ' + [name] +
'=NULL' AS
[text()]
FROM sys.parameters
WHERE [object_id] = SM.[object_id]
FOR XML PATH('')
),
1,
1,
''
)
)
)
FOR XML RAW,
TYPE
).value('/row[1]', 'varchar(max)')
)
FROM sys.sql_modules SM
JOIN sys.objects SO
ON SO.[object_id] = SM.[object_id]
WHERE SO.[is_ms_shipped] = 0
AND SO.[type] = 'P'
OPEN testSPs
FETCH NEXT FROM testSPs INTO @name, @type, @type_desc, @params
WHILE (@@FETCH_STATUS = 0)
BEGIN
BEGIN TRY
SET @sql = 'SET FMTONLY ON; exec ' + @name + ' ' + @params +
'; SET FMTONLY OFF;'
--PRINT @sql;
EXEC (@sql) ;
END TRY
BEGIN CATCH
PRINT @type_desc + ', ' + @name + ', Error: ' + CAST(ERROR_NUMBER() AS VARCHAR)
+ ', ' + ERROR_MESSAGE();
INSERT INTO @tblInvalid
SELECT @type_desc,
@name,
ERROR_NUMBER(),
ERROR_MESSAGE(),
@type
;
END CATCH
FETCH NEXT FROM testSPs INTO @name, @type, @type_desc, @params
END
CLOSE testSPs
DEALLOCATE testSPs
SELECT [type_desc],
[name],
[error_number],
[error_message]
FROM @tblInvalid
ORDER BY
CHARINDEX([type], ' U V PK UQ F TR FN TF P SQ '),
[name];
توضیحات:
این کوئری، در دیتابیس جاری که در قسمت use dbname مشخص میشود، تمامی رویههای ذخیره شده را به صورت خودکار پیدا میکند. سپس لیست آرگومانهای آنها را نیز یافته و عبارت exec مربوطه را تشکیل میدهد. سپس با استفاده از SET FMTONLY ON سعی در شبیه سازی اجرای تک تک رویههای ذخیره شده میکند. اگر خطایی در این بین رخ داد، آنها را در یک جدول موقتی ذخیره کرده و در آخر نتیجه را نمایش میدهد.
ارزش این کوئری زمانی مشخص میشود که تعداد زیادی رویه ذخیره شده داشته باشید اما نمیدانید کدامیک از آنها بر اساس آخرین تغییرات صورت گرفته، هنوز معتبر هستند یا نه. آیا به قول معروف، سیستم اومد پایین یا خیر!؟
نکته:
قسمتی که از XML استفاده شده جهت concatenating نتیجه حاصل از کوئری، مورد استفاده قرار گرفته و این روزها بحث رایجی است که در بسیاری از سایتها در مورد آن میتوان مطالب مفیدی را یافت. راه دیگر انجام آن استفاده از COALESCE میباشد.
مآخذ:
Check Validity of SQL Server Stored Procedures
Which of your Stored Procedures are no longer Valid
SET FMTONLY ON
یکی از ویژگیهای زبان VB، شباهت بیش از اندازهی آن به زبان انگلیسی است. برای مثال در این زبان با استفاده از not و and:
میتوان ifهای خواناتری را نسبت به #C ایجاد کرد:
در ادامه خواهیم دید که چگونه C# 9.0، این آرزوی دیرین را برآورده میکند! البته مایکروسافت در جای دیگری هم عنوان کردهاست که زبان VB را دیگر پیگیری نمیکند و تغییر خاصی را در آن شاهد نخواهید بود. شاید به همین دلیل و جذب برنامه نویسهای VB به #C، یک چنین تغییراتی رخ دادهاند!
معرفی واژهی کلیدی جدید not در C# 9.0
در ابتدا اینترفیس نمونهای را به همراه دو کلاس مشتق شدهی از آن درنظر بگیرید:
اکنون اگر وهلهای از Command1 را ایجاد کرده و بخواهیم بررسی کنیم که آیا از نوع کلاس Command2 هست یا خیر، با استفاده از pattern matching و واژهی کلیدی if میتوان به صورت زیر عمل کرد:
در C# 9.0، برای خواناتر کردن یک چنین بررسیهایی، میتوان از pattern matching بهبود یافتهی آن و واژهی کلیدی جدید not نیز استفاده کرد:
معرفی واژههای کلیدی جدید and و or در C# 9.0
واژههای کلیدی جدید and و or نیز درک و نوشتن عبارات pattern matching را بسیار ساده میکنند. برای نمونه قطعه کد متداول زیر را درنظر بگیرید:
اکنون در C# 9.0 با استفاده از واژههای کلیدی جدید and، or و not، میتوان قطعه کد فوق را بسیار ساده کرد:
نه تنها این قطعه کد سادهتر شدهاست، بلکه خوانایی آن افزایش یافتهاست و مانند یک سطر نوشته شدهی به زبان انگلیسی به نظر میرسد. همچنین در این حالت نیازی هم به تکرار command، در هر بار مقایسه نیست.
و یا حتی در اینجا در صورت نیاز میتوان از واژهی کلیدی جدید or نیز استفاده کرد:
امکان اعمال واژههای کلیدی جدید and، or و not به سایر نوعها نیز وجود دارند
تا اینجا مثالهایی را که بررسی کردیم، در مورد بررسی نوع اشیاء بود. اما میتوان این واژههای کلیدی جدید در C# 9.0 را به هر نوع ممکنی نیز اعمال کرد. برای نمونه، مثال سادهی زیر را که در مورد بررسی اعداد است، درنظر بگیرید:
اکنون در C# 9.0 و با استفاده از امکانات جدید pattern matching آن میتوان شرط متداول فوق را به صورت زیر ساده کرد:
در اینجا تنها یکبار نیاز به ذکر number است و از واژههای کلیدی is و and استفاده شدهاست.
یک مثال دیگر: متد زیر را در نظربگیرید که با استفاده از && و || متداول #C نوشته شدهاست:
روش ارائهی C# 9.0 ای آن به صورت زیر است:
امکان اعمال واژههای کلیدی جدید and، or و not به switchها نیز وجود دارد
برای نمونه قطعه کد if/else دار متداول زیر را درنظر بگیرید که قابلیت تبدیل به یک سوئیچ را نیز دارد:
اگر بخواهیم همین قطعه کد را به کمک واژههای کلیدی جدید C# 9.0 و pattern matching بهبود یافتهی آن تبدیل به یک سوئیچ کنیم، به قطعه کد زیر خواهیم رسید:
تا پیش از C# 7.0، سوئیچهای #C امکان بررسی بازهای از مقادیر را نداشتند. از آن زمان با معرفی pattern matching، چنین محدودیتی برطرف شد و اکنون میتوان syntax قدیمی آنرا توسط C# 9.0، بسیار خلاصهتر کرد. در ذیل، معادل قطعه کد فوق را بر اساس امکانات C# 7.0 مشاهده میکنید که خوانایی کمتری را داشته و حجم کد نویسی بیشتری را دارد:
و یا حتی میتوان سوئیچ C# 9.0 را توسط switch expression بهبود یافتهی C# 8.0 نیز به شکل زیر بازنویسی کرد:
انواع pattern matchingهای اضافه شدهی به C# 9.0
در این مطلب سعی شد مفاهیم pattern matching اضافه شدهی به C# 9.0، ذیل عنوان واژههای کلیدی جدید آن بحث شوند؛ اما هر کدام دارای نامهای خاصی هم هستند:
الف) relational patterns: امکان استفادهی از <, >, <= and >= را در الگوها میسر میکنند. مانند نمونههای سوئیچی که نوشته شد.
ب) logical patterns: امکان استفادهی از واژههای کلیدی and، or و not را در الگوها ممکن میکنند.
ج) not pattern: امکان استفادهی از واژهی کلیدی not را در عبارات if میسر میکند.
د) Simple type pattern: در مثالهای زیر، پس از انطباق با یک الگو، کاری با متغیر یا شیء مرتبط نداریم. در نگارشهای قبلی برای صرفنظر کردن از آن، ذکر _ ضروری بود؛ اما در C#9.0 میتوان آنرا نیز ذکر نکرد:
If Not a And b Then ... Else ... EndIf
if(!(a) && b) { ... } else { }
معرفی واژهی کلیدی جدید not در C# 9.0
در ابتدا اینترفیس نمونهای را به همراه دو کلاس مشتق شدهی از آن درنظر بگیرید:
public interface ICommand { } public class Command1 : ICommand { } public class Command2 : ICommand { }
ICommand command = new Command1(); if (!(command is Command2)) { }
if (command is not Command2) { }
معرفی واژههای کلیدی جدید and و or در C# 9.0
واژههای کلیدی جدید and و or نیز درک و نوشتن عبارات pattern matching را بسیار ساده میکنند. برای نمونه قطعه کد متداول زیر را درنظر بگیرید:
if ((command is ICommand) && !(command is Command2)) { }
if (command is ICommand and not Command2) { }
و یا حتی در اینجا در صورت نیاز میتوان از واژهی کلیدی جدید or نیز استفاده کرد:
if (command is Command1 or Command2) { }
امکان اعمال واژههای کلیدی جدید and، or و not به سایر نوعها نیز وجود دارند
تا اینجا مثالهایی را که بررسی کردیم، در مورد بررسی نوع اشیاء بود. اما میتوان این واژههای کلیدی جدید در C# 9.0 را به هر نوع ممکنی نیز اعمال کرد. برای نمونه، مثال سادهی زیر را که در مورد بررسی اعداد است، درنظر بگیرید:
var number = new Random().Next(1, 10); if (number > 2 && number < 8) { }
if (number is > 2 and < 8) { }
یک مثال دیگر: متد زیر را در نظربگیرید که با استفاده از && و || متداول #C نوشته شدهاست:
public static bool IsLetterOrSeparator(char c) => (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '.' || c == ',';
public static bool IsLetterOrSeparator(char c) => c is (>= 'a' and <= 'z') or (>= 'A' and <= 'Z') or '.' or ',';
امکان اعمال واژههای کلیدی جدید and، or و not به switchها نیز وجود دارد
برای نمونه قطعه کد if/else دار متداول زیر را درنظر بگیرید که قابلیت تبدیل به یک سوئیچ را نیز دارد:
var number = new Random().Next(1, 10); if (number <= 0) { Console.WriteLine("Less than or equal to 0"); } else if (number > 0 && number <= 10) { Console.WriteLine("More than 0 but less than or equal to 10"); } else { Console.WriteLine("More than 10"); }
// C#9.0 switch (number) { case <= 0: Console.WriteLine("Less than or equal to 0"); break; case > 0 and <= 10: Console.WriteLine("More than 0 but less than or equal to 10"); break; default: Console.WriteLine("More than 10"); break; }
// C#7.0 switch (number) { case int value when value <= 0: Console.WriteLine("Less than or equal to 0"); break; case int value when value > 0 && value <= 10: Console.WriteLine("More than 0 but less than or equal to 10"); break; default: Console.WriteLine("More than 10"); break; }
و یا حتی میتوان سوئیچ C# 9.0 را توسط switch expression بهبود یافتهی C# 8.0 نیز به شکل زیر بازنویسی کرد:
var message = number switch { <= 0 => "Less than or equal to 0", > 0 and <= 10 => "More than 0 but less than or equal to 10", _ => "More than 10" };
انواع pattern matchingهای اضافه شدهی به C# 9.0
در این مطلب سعی شد مفاهیم pattern matching اضافه شدهی به C# 9.0، ذیل عنوان واژههای کلیدی جدید آن بحث شوند؛ اما هر کدام دارای نامهای خاصی هم هستند:
الف) relational patterns: امکان استفادهی از <, >, <= and >= را در الگوها میسر میکنند. مانند نمونههای سوئیچی که نوشته شد.
ب) logical patterns: امکان استفادهی از واژههای کلیدی and، or و not را در الگوها ممکن میکنند.
ج) not pattern: امکان استفادهی از واژهی کلیدی not را در عبارات if میسر میکند.
د) Simple type pattern: در مثالهای زیر، پس از انطباق با یک الگو، کاری با متغیر یا شیء مرتبط نداریم. در نگارشهای قبلی برای صرفنظر کردن از آن، ذکر _ ضروری بود؛ اما در C#9.0 میتوان آنرا نیز ذکر نکرد:
private static int GetDiscount(Product p) => p switch { Food => 0, // Food _ => 0 before C# 9 Book b => 75, // Book b _ => 75 before C# 9 _ => 25 };
نظرات مطالب
مروری بر کاربردهای Action و Func - قسمت اول
نمیتوان. چون در اصل Action و Func به این صورت تعریف شدهاند:
public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2); public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);
+ از زمان C# 7.0 اگر نیاز به نامگذاری این پارامترها را داشتید، میتوانید از tuples به صورت زیر استفاده کنید:
Func<(string firstName, string lastName), string> f = (data) => data.firstName + data.lastName; f(("Foo", "Bar"));