مسیرراه‌ها
+AngularJS 2.0
شروع به کار با AngularJS 2.0 و TypeScript
فرم‌های مبتنی بر قالب‌ها در Angular
Angular Animation
آپلود فایل
Angular Material 6x
  • ابزارهای توسعه
بازخوردهای دوره
استفاده از Async و Await در برنامه‌های ASP.NET MVC
- پیشنیاز مطالعه قسمت جاری، مطالعه 6 قسمت اول این دوره است.
- «همزمان اجرا میشه»
خیر. متدهای Async واقعی مثل نمونه ارائه شده در EF غیرهمزمان اجرا می‌شوند. یعنی، ترد جاری را آزاد کرده و ASP.NET می‌تواند از آن ترد برای پاسخ دهی به یک درخواست رسیده دیگر استفاده کند.
- «باید منتظر پاسخ از db بمونه»
استفاده از await و async سبب بازنویسی بدنه متد توسط یک state machine در پشت صحنه می‌شوند. یعنی اینطور نیست که روش اجرای آن blocking است و تا رسیدن پاسخ از بانک اطلاعاتی، از این ترد دیگر نمی‌شود استفاده کرد. جایی که await فراخوانی می‌شود، ترد جاری برای استفاده بعدی آزاد خواهد شد. در ادامه مابقی کدها تبدیل به یک IEnumerator می‌شوند که هر دستور آن شامل یک yield return است. هر مرحله که تمام شد، MoveNext این IEnumerator فراخوانی می‌شود تا به مرحله‌ی بعدی برسد. به این روش استفاده از coroutines هم گفته می‌شود که در سی شارپ 5، کامپایلر کار تولید کدهای آن‌را انجام می‌دهد. برای مطالعه بیشتر:
انجام پی در پی اعمال Async به کمک Iterators - قسمت اول  
انجام پی در پی اعمال Async به کمک Iterators - قسمت دوم
- «چون تا فایل آپلود نشه ذخیره آدرس تو db بی معنیه»
ذخیره آدرس هم یک قسمت از کار است و اتفاقا وابسته به سیستم جاری هم نیست. وابسته است به یک بانک اطلاعاتی که خارج از مرزهای سیستم، به صورت مستقل در حال فعالیت است (عموما البته؛ مثلا اگر از SQL Server استفاده می‌شود).
برای ذخیره فایل‌ها در سیستم هم متدهای Async به کلاس Stream در دات نت 4.5 اضافه شده‌اند؛ مثل WriteAsync . در این حالت هم می‌توان از await WriteAsync برای ذخیره اطلاعات و بازهم آزاد کردن ترد جاری استفاده کرد.
نظرات نظرسنجی‌ها
آیا به یادگیری یا ادامه‌ی استفاده از AngularJS خواهید پرداخت؟
AngularJS فریم ورک خوبیه، ولی مشکلات زیادی داره. اول از همه اینکه در فاز تحقیقاتی هست و بر خلاف ادعا هایی که وجود داره Google در محصولات یا پروژه‌های داخلیش ازش استفاده نمی‌کنه. ثانیا تا اوایل سال 2016 انتشار مهمی (major release) نخواهیم دید و نسخه 2.0 فریم ورک کاملا جدیدی خواهد بود. بنابراین نه تنها backward compatibility نخواهیم داشت بلکه تمام تجربه و دانش فعلی عملا بلا استفاده خواهند بود و باید همه چیز رو از ابتدا یاد گرفت. باید منتظر بود تا نسخه بعدی منشر بشه و اگر اون موقع تیم Angular تونست نسبت به رقبای دیگش حرف اول رو بزنه، می‌تونیم بریم سراغش و فریم ورک‌های دیگه رو کنار بگذاریم.

در نگاه اول شاید برای توسعه دهندگان مبتدی یک سری مباحث گیج کننده باشن و خیلی از قابلیت‌ها هم جادویی و جذاب. اما حقیقت امر این است که code base این فریم ورک مشکلات شگفت آوری داره. چند ساعت وقت گذاشتن روی اینترنت کافی هست تا از تمام جنبه‌ها فریم ورک‌های مطرح رو بررسی کرد و متوجه شد که Angular چقدر مشکلات اساسی داره. بصورت تیتر وار چند مورد رو لیست می‌کنم:
  • Dynamic Scoping, and scope inheritance
  • Two-way data binding with $watchers
  • The $digest cycle
  • No DOM manipulation capabilities
  • Finite Routing, unless you use a 3rd party like ui-router
  • app logic and structure expressed in HTML
  • No server-side rendering (mostly for speed boost and SEO)
  • string-based Dependency Injection
  • Ill-Conceived architecture (obsolete constructor functions etc)
  • Debugging issues
  • Re-defining well established terminology
  • Syntactic Sugar
  • Execution Contexts
  • Unnecessary Complications
  • Incompatible with 3rd party libraries, like jQuery etc.
  • Sparse documentation with literally no real-world examples

و مواردی از این دست. شاید برای پروژه‌های کوچک این فریم ورک مناسب باشه اما قطعا برای پروژه‌های بزرگی که قرار است برای مدتی طولانی توسعه داده بشن و نگهداری بشن اصلا انتخاب درستی نیست. حتی اگر پروژه‌های بزرگی هم با موفقیت توسط این فریم اجرا شده باشه باز هم ماهیت مساله تغییر نمی‌کنه.

در حال حاظر بین فریم ورک‌های دیگه بهترین انتخاب Ember هست که بسیاری از مشکلات ذکر شده رو نداره و ساختار و معماری قوی و خوبی هم داره. Backbone و Durandal هم فریم ورک‌های قوی ای هستند ولی تفاوت‌های نسبتا زیادی با Ember دارن.

حائز اهمیت این که، اپلیکیشن‌های SPA جوان هستند و فعلا همه جای دنیا در حال آزمایش و بررسی این هستند که چطور میشه چنین پروژه هایی رو اجرا کرد و کدام راه بهترین راه هست، بنابراین تا به استاندارد‌های ثابتی برسیم راه طولانی ای در پیش داریم. از طرفی بزودی استاندارد جدید جاوا اسکریپت (ECMA6) منتشر میشه، که با انتشارش فریم ورک هایی مثل Ember و Angular رو کاملا به هم خواهد ریخت. مثلا در نسخه جدید آبجکت‌های Observable خواهیم داشت. بنابراین متدهای Angular و Ember برای تشخیص تغییرات به کلی بلا استفاده خواهند بود و بازنویسی‌های اساسی لازم می‌شود.

مطالب
Best Practice هایی برای طراحی RESTful API - قسمت اول

با آمدن Asp.Net Web API کار ساختن Web API‌ها برای برنامه نویس‌ها به خصوص دسته ای که با ساخت API و وب سرویس آشنا نبودند خیلی ساده‌تر شد . اگر با Asp.Net MVC آشنا باشید خیلی سریع می‌توانید اولین Web Service خودتان را بسازید .

در صفحه مربوط به Asp.Net Web API آمده است که این فریمورک بستر مناسبی برای ساخت و توسعه برنامه ‌های RESTful است . اما تنها ساختن کنترلر و اکشن و برگشت دادن داده‌ها به سمت کلاینت ، به خودی خود برنامه شما رو تبدیل به یک RESTful API نمی‌کند .

مثل تمام مفاهیم و ابزارها ، طراحی و ساختن RESTful API هم دارای اصول و Best Practice هایی است که رعایت آنها به خصوص در این زمینه از اهمیت زیادی برخوردار است . همانطور که از تعریف API برمی آید شما در حال طراحی رابطی هستید تا به توسعه دهندگان دیگر امکان دهید از داده‌ها و یا خدمات شما در برنامه‌ها و سرویس هایشان استفاده کنند . مانند API‌های توئیتر و نقشه گوگل که برنامه‌های زیادی بر مبنای آنها ساخته شده اند . در واقع  توسعه دهندگان مشتریان API شما هستند .

بهره وری توسعه دهنده مهمترین اصل

اینطور می‌توان نتیجه گرفت که اولین و مهمترین اصل در طراحی API باید رضایت و موفقیت توسعه دهنده در درک و یادگیری سریع API شما ،نه تنها با کمترین زحمت بلکه همراه با حس نشاط ، باشد. ( تجربه کاربری در اینجا هم می‌تواند صدق کند ). سعی کنید در زمان انتخاب از بین روش‌های طراحی موجود ، از دیدگاه توسعه دهنده به مسئله نگاه کنید . خود را به جای او قرار دهید و تصور کنید که می‌خواهید با استفاده از API موجود یک رابط کاربری طراحی کنید یا یک اپلیکشن برای موبایل بنویسید و اصل را این نکته قرار دهید که بهره وری برنامه نویس را حداکثر کنید. ممکن است گاهی بین طرحی که بر اساس این اصل برای API خود در نظر داریم و یکی از اصول یا استانداردها تعارض بوجود بیاید . در این موارد بعد از اینکه مطمئن شدیم این اختلاف ناشی از طراحی و درک اشتباه خودمان نیست (که اکثرا هست ) ارجحیت را باید به طراحی بدهیم . 


تهیه مستندات API

اگر برای پروژه وب سایتتان هیچ نوشته ای یا توضیحی ندارید ، جالب نیست اما خودتان ساختار برنامه خود را می‌شناسید و کار را پیش می‌برید. اما توسعه دهنده ای که از API شما می‌خواهد استفاده کند و به احتمال زیاد شما را نمی‌شناسد ، عضو تیم شما هم نیست ، هیچ ایده ای درباره ساختار آن ، روش نامگذاری توابع و منابع، ساختار Url‌‌ها ، چگونگی و گام‌های پروسه درخواست تا دریافت پاسخ ندارد ،و به مستندات شما وابسته است و تمام اینها باید در مستندات شما باشد. بیشتر توسعه دهنده‌ها قبل از تست کردن API شما سری به مستندات می‌زنند ، دنبال نمونه کد آموزشی می‌گردند و در اینترنت درباره آن جستجو می‌کنند . ازینرو مستندات ( کارامد ) یک ضرورت است :
1- در مستندات باید هم درباره کلیت و هم در مورد تک تک توابع ( پارامترهای معتبر ، ساختار پاسخ‌ها و ... ) توضیحات وجود داشته باشد.
2- باید شامل مثالهایی از سیکل کامل درخواست‌ها / پاسخ‌ها باشند .
3- تغییرات اعمال شده نسبت به نسخه‌های قبلی باید در مستندات بیان شوند .
4- (در وب ) یافتن و جستجو کردن در مستنداتی که به صورت فایل Pdf هستند یا برای دسترسی نیاز به Login داشته باشند سخت و آزاردهنده هستند.
5- کسی را داشته باشید تا با و بدون مستندات با API شما کار کند و از این روش برای تکمیل و اصلاح مستندات استفاده کنید.

رعایت نسخه بندی و حفظ نسخه‌های قبلی به صورت فعال برای مدت معین
یک API  تقریبا هیچوقت کاملا پایدار نمی‌شود و اعمال تغییرات برای بهبود آن اجتناب ناپذیر هستند . مسئله مهم این است که چطور این تغییرات مدیریت شوند . مستند کردن تغییرات ، اعلام به موقع آنها و دادن یک بازه زمانی کافی برای ارتقا یافتن برنامه هایی که از نسخه‌های قدیمی‌تر استفاده می‌کنند نکات مهمی هستند . همیشه در کنار نسخه بروز و اصلی یک یا دو نسخه ( بسته به API و کلاینت‌های آن ) قدیمی‌تر را برای زمان مشخصی در حالت سرویس دهی داشته باشید .

داشتن یک روش مناسب برای اعلام تغییرات و ارائه مستندات و البته دریافت بازخورد از استفاده کنندگان
تعامل با کاربران برنامه باید از کانال‌های مختلف وجود داشته باشد .از وبلاگ ، Mailing List ، Google Groups و دیگر ابزارهایی که در اینترنت وجود دارند برای انتشار مستندات ، اعلام بروزرسانی‌ها ، قرار دادن مقالات و نمونه کدهای آموزشی ، پرسش و پاسخ با کاربران استفاده کنید .

مدیریت خطاها به شکل صحیح که به توسعه دهنده در آزمودن برنامه اش کمک کند.
از منظر برنامه نویسی که از API شما استفاده می‌کند هرآنچه در آنسوی API اتفاق می‌افتد یک جعبه سیاه است . به همین جهت خطاهای API شما ابزار کلیدی برای او هستند که خطایابی و اصلاح برنامه در حال توسعه اش را ممکن می‌کنند . علاوه بر این ، زمانی که برنامه نوشته شده با API شما مورد استفاده کاربر نهایی قرار گرفت ، خطاهای به دقت طراحی شده API شما کمک بزرگی برای توسعه دهنده در عیب یابی هستند .
1- از Status Code های HTTP استفاده کنید و سعی کنید تا حد ممکن آنها را نزدیک به مفهوم استانداردشان بکار ببرید .
2- خطا و علت آن را به زبان روشن توضیح دهید و در توضیح خساست به خرج ندهید .
3- در صورت امکان لینکی به یک صفحه وب که حاوی توضیحات بیشتری است را در خطا بگنجانید .

رعایت ثبات و یکدستی در تمام بخش‌های طراحی که توانایی پیش بینی توسعه دهنده را در استفاده از API افزایش می‌دهد .
داشتن مستندات لازم است اما این بدین معنی نیست که خود API نباید خوانا و قابل پیش بینی باشد . از هر روش و تکنیکی که استفاده می‌کنید آن را در تمام پروژه حفظ کنید . نامگذاری توابع/منابع ، ساختار پاسخ‌ها ، Url‌‌ها ، نقش و عملیاتی که HTTP method‌‌ها در API شما انجام می‌دهند باید ثبات داشته باشند . از این طریق توسعه دهنده لازم نیست برای هر بخشی از API شما به سراغ فایل‌ها راهنما برود . و به سرعت کار خود را به پیش می‌برد .

انعطاف پذیر بودن API
API توسط کلاینت‌های مختلفی و برای افراد مختلفی مورد استفاده قرار می‌گیرد که لزوما همه‌ی آنها ساختار یکسانی ندارند و API شما باید تا جای ممکن بتواند همه آنها را پوشش دهد . محدود بودن فرمت پاسخ ، ثابت بودن فیلدهای ارسالی به کلاینت ، ندادن امکان صفحه بندی ، مرتب سازی و جستجو در داده‌ها به کلاینت ، داشتن تنها یک نوع احراز هویت ، وابسته بودن به کوکی و ... از مشخصات یک API منجمد و انعطاف ناپذیر هستند . 

اینها اصولی کلی بودند که بسیاری از آنها مختص طراحی API نیستند و در تمام حوزه‌ها قابل استفاده بوده ، جز الزامات هستند . در قسمت‌های بعدی نکات اختصاصی‌تری را بررسی خواهیم کرد .
نظرات مطالب
معرفی قالب پروژه Web API مبتنی‌بر ASP.NET Core Web API و زیرساخت DNTFrameworkCore
- انتقال منابع به یک اسمبلی دیگر «ارتقاء به ASP.NET Core 1.0 - قسمت 19 - بومی سازی»
- هدف اصلی آنها دسته‌بندی منابع می‌باشد. می‌توانید صرفا از ISharedLocalizer استفاده کنید یا به صورت مستقیم IStringLocalizer<SharedResource>‎ را تزریق کنید.
مطالب
پشتیبانی از حذف و به‌روز رسانی دسته‌ای رکوردها در EF 7.0
همواره حذف و به روز رسانی تعداد زیادی رکورد توسط EF، بسیار غیربهینه و کند بوده‌است؛ از این جهت که یکی از روش‌های انجام اینکار، کوئری گرفتن از رکوردهای مدنظر جهت حذف، سپس بارگذاری آن‌ها در حافظه و در آخر حذف یکی یکی آن‌ها بوده‌است:
using var dbContext = new MyDbContext();
var objectToDelete = await dbContext.Objects.FirstAsync(o => o.Id == id);
dbContext.Objects.Remove(objectToDelete);
await dbContext.SaveChangesAsync();
در اینجا در ابتدا، شیء‌ای که قرار است حذف شود، از بانک اطلاعاتی کوئری گرفته می‌شود تا وارد سیستم Change Tracking شود. سپس از این سیستم ردیابی اطلاعات درون حافظه‌ای، حذف خواهد شد و در نهایت این تغییرات به بانک اطلاعاتی اعمال می‌شوند. بنابراین در این مثال ساده، حداقل دوبار رفت و برگشت به بانک اطلاعاتی وجود خواهد داشت.
البته راه دومی نیز برای انجام اینکار وجود دارد:
using var dbContext = new MyDbContext();
var objectToDelete = new MyObject { Id = id };
dbContext.Objects.Remove(objectToDelete);
await dbContext.SaveChangesAsync();
در این مثال، رفت و برگشت ابتدایی، حذف شده‌است و با فرض معلوم بودن کلید اصلی رکورد مدنظر، آن‌را وارد سیستم Change Tracking کرده و درنهایت آن‌را حذف می‌کنیم. کار متد Remove در اینجا، علامتگذاری این شیء دارای Id، به صورت EntityState.Deleted است.

اکنون می‌توان در EF 7.0، روش سومی را نیز به این لیست اضافه کرد که فقط یکبار رفت و برگشت به بانک اطلاعاتی را سبب می‌شود:
await dbContext.Objects.Where(x => x.Id == id).ExecuteDeleteAsync();


معرفی متدهای حذف و به‌روز رسانی دسته‌ای رکوردها در EF 7.0

EF 7.0 به همراه دو متد جدید ExecuteUpdate و ExecuteDelete (و همچنین نگارش‌های async آن‌ها) است که کار به‌روز رسانی و یا حذف دسته‌ای رکوردها را بدون دخالت سیستم Change tacking میسر می‌کنند. مزیت مهم این روش، عدم نیاز به کوئری گرفتن از بانک اطلاعاتی جهت بارگذاری رکوردهای مدنظر در حافظه و سپس حذف یکی یکی آن‌ها است. فقط باید دقت داشت که چون این روش خارج از سیستم Change tracking صورت می‌گیرد، نتیجه‌ی حاصل، دیگر با اطلاعات درون حافظه‌ای سمت کلاینت، هماهنگ نخواهد بود و کار به روز رسانی دستی آن‌ها به‌عهده‌ی شماست.


بررسی نحوه‌ی عملکرد ExecuteUpdate و ExecuteDelete با یک مثال

فرض کنید مدل‌های موجودیت‌های برنامه شامل کلاس‌های زیر هستند:
public class User
{
    public int Id { get; set; }
    public required string FirstName { get; set; }
    public required string LastName { get; set; }
    public virtual List<Book> Books { get; set; } = new();
    public virtual Address? Address { get; set; }
}

public class Book
{
    public int Id { get; set; }
    public required string Type { get; set; }
    public required string Name { get; set; }

    public virtual User User { get; set; } = default!;
    public int UserId { get; set; }
}

public class Address
{
    public int Id { get; set; }
    public required string Street { get; set; }
    
    public virtual User User { get; set; } = default!;
    public int UserId { get; set; }
}
که در اینجا یک کاربر می‌تواند دارای یک آدرس و چندین کتاب تعریف شده باشد؛ با این Context ابتدایی:
public class ApplicationDbContext : DbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
    {
    }

    public DbSet<User> Users { get; set; } = default!;

    public DbSet<Book> Books { get; set; } = default!;

    public DbSet<Address> Addresses { get; set; } = default!;
}

مثال 1: حذف دسته‌ای تعدادی کتاب
context.Books.Where(book => book.Name.Contains("1")).ExecuteDelete();
در اینجا نحوه‌ی استفاده از متد ExecuteDelete را مشاهده می‌کنید که به انتهای LINQ Query، اضافه شده‌است. در این مثال، تمام کتاب‌هایی که در نامشان حرف 1 وجود دارد، حذف می‌شوند. این کوئری، به صورت زیر بر روی بانک اطلاعاتی اجرا می‌شود:
DELETE FROM [b]
FROM [Books] AS [b]
WHERE [b].[Name] LIKE N'%1%'
مهم‌ترین مزیت این روش، عدم نیاز به بارگذاری و یا ساخت درون حافظه‌ای لیست کتاب‌هایی است که قرار است حذف شوند. کل این عملیات در یک رفت و برگشت ساده و سریع انجام می‌شود.

یک نکته: متد ExecuteDelete، تعداد رکوردهای حذف شده را نیز بازگشت می‌دهد.


مثال 2: حذف کاربران و تمام رکوردهای وابسته به آن

فرض کنید می‌خواهیم تعدادی از کاربران را از بانک اطلاعاتی حذف کنیم:
context.Users.Where(user => user.Id <= 500).ExecuteDelete();
اگر این کوئری را با تنظیمات فعلی اجرا کنیم، با خطای زیر متوقف خواهیم شد:
DELETE FROM [u]
FROM [Users] AS [u]
WHERE [u].[Id] <= 500

The DELETE statement conflicted with the REFERENCE constraint "FK_Books_Users_UserId".
The conflict occurred in database "EF7BulkOperations", table "dbo.Books", column 'UserId'.
عنوان می‌کند که یک کاربر، دارای تعدادی کتاب و آدرسی از پیش ثبت شده‌است و نمی‌توان آن‌را بدون حذف وابستگی‌های آن، حذف کرد. اگر کاربری را حذف کنیم، کلید‌های خارجی ذکر شده‌ی در جداولی که این کلید خارجی را به همراه دارند، غیرمعتبر می‌شوند (و این کلید خارجی تعریف شده، نال پذیر هم نیست). برای رفع این مشکل، یا باید ابتدا در طی دستوراتی جداگانه، وابستگی‌های ممکن را حذف کنیم و یا می‌توان تنظیم cascade delete را به نحو زیر به تعریف جداول مرتبط اضافه کرد تا صدور یک دستور delete، به صورت خودکار سبب حذف وابستگی‌های مرتبط نیز شود:
public class ApplicationDbContext : DbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
    {
    }

    public DbSet<User> Users { get; set; } = default!;

    public DbSet<Book> Books { get; set; } = default!;

    public DbSet<Address> Addresses { get; set; } = default!;

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder
            .Entity<User>()
            .HasMany(user => user.Books)
            .WithOne(book => book.User)
            .OnDelete(DeleteBehavior.Cascade);

        modelBuilder
            .Entity<User>()
            .HasOne(user => user.Address)
            .WithOne(address => address.User)
            .HasForeignKey<Address>(address => address.UserId)
            .OnDelete(DeleteBehavior.Cascade);
    }
}
همانطور که ملاحظه می‌کنید، به متد OnModelCreating تنظیم cascade delete وابستگی‌های جدول کاربران اضافه شده‌است. پس از این تنظیم، دستور مثال دوم، بدون مشکل اجرا شده و حذف یک کاربر، سبب حذف خودکار کتاب‌ها و آدرس او نیز می‌شود.


مثال 3: به‌روز رسانی دسته‌ای از کاربران

فرض کنید می‌خواهیم LastName تعدادی کاربر مشخص را به مقدار جدید Updated، تغییر دهیم:
context.Users.Where(user => user.Id <= 400)
   .ExecuteUpdate(p => p.SetProperty(user => user.LastName,  user => "Updated"));
برای اینکار، پس از مشخص شدن شرط کوئری در قسمت Where، کار به روز رسانی توسط متد ExecuteUpdate و سپس متد SetProperty صورت می‌گیرد. در اینجا در ابتدا مشخص می‌کنیم که کدام خاصیت قرار است به روز رسانی شود و پارامتر دوم آن، مقدار جدید را مشخص می‌کند. این کوئری به نحو زیر به بانک اطلاعاتی اعمال خواهد شد:
UPDATE [u]
SET [u].[LastName] = N'Updated'
FROM [Users] AS [u]
WHERE [u].[Id] <= 400
در اینجا می‌توان در پارامتر دوم متد SetProperty، از مقدار فعلی سایر خواص نیز استفاده کرد:
context.Users.Where(user => user.Id <= 300)
  .ExecuteUpdate(p => p.SetProperty(user => user.LastName,
      user => "Updated" + user.LastName));
که خروجی زیر را تولید می‌کند:
UPDATE [u]
SET [u].[LastName] = N'Updated' + [u].[LastName]
FROM [Users] AS [u]
WHERE [u].[Id] <= 300
همچنین می‌توان چندین متد SetProperty را نیز به صورت زنجیروار، جهت به روز رسانی چندین خاصیت و فیلد، ذکر کرد:
context.Users.Where(user => user.Id <= 800)
   .ExecuteUpdate(p => p.SetProperty(user => user.LastName,
        user => "Updated" + user.LastName)
             .SetProperty(user => user.FirstName,
                 user => "Updated" + user.FirstName));
با این خروجی نهایی:
UPDATE [u]
SET [u].[FirstName] = N'Updated' + [u].[FirstName],
[u].[LastName] = N'Updated' + [u].[LastName]
FROM [Users] AS [u]
WHERE [u].[Id] <= 800
متد ExecuteUpdate، تعداد رکوردهای به‌روز رسانی شده را نیز بازگشت می‌دهد.


کدهای کامل این مطلب را از اینجا می‌توانید دریافت کنید:  EF7BulkOperations.zip
اشتراک‌ها
واکشی اطلاعات فایل XML با استفاده از کتابخانه jQuery

فرض کنید می‌خواهید اطلاعات موجود در فایل محلی index.xml که لیست از کتاب‌های در آن درج شده است با استفاده از کتابخانه jQuery بخوانیم، یعنی امکان برنامه نویسی سمت سرور نداریم و می‌خواهیم با استفاده از زبان اسکریپتی جاوااسکریپت لیست کتاب‌ها را به کاربران نمایش دهیم...

واکشی اطلاعات فایل XML با استفاده از کتابخانه jQuery
اشتراک‌ها
فرم ساز JQuery

کاربردهای این فرم سازها:

در سیستم‌های گردش کار، گاهی اوقات نیاز میشود از کاربران مواردی پرسیده شود.

در سیستم‌های معمول هم مانند نظرسنجی، نحوه کار، موارد مورد نیاز با روند و...

ویژگی‌های پلاگین:(داکیومنت کامل)

1- سادگی

2- پشتیبانی پیشفرض از زبان فارسی

3- ذخیره اطلاعات به صورت JSON و ویرایش آن به راحتی

4- امکان مشاهده پیش نمایش در زمان ویرایش

این فرم ساز هم در نظر داشته باشید لطفا 

فرم ساز JQuery
نظرات مطالب
EF Code First #10
در تمام ORMها استفاده میشه. NHibernate هم نوع خاص خودش را دارد. در EF از کلاس‌های پروکسی به دو منظور Lazy loading و change tracking استفاده میشه. به همین جهت خواصی که در lazy loading مورد استفاده قرار می‌گیرند باید virtual تعریف شوند. به این ترتیب ORM مورد استفاده می‌تونه این خواص رو جهت کاربردهای خودش، به صورت پویا بازنویسی و override کنه. با تنظیم DbContext.Configuration.ProxyCreationEnabled=false ، دو کاربرد یاد شده از کار خواهند افتاد. اطلاعات بیشتر رو می‌تونید در بلاگ یکی از اعضای تیم EF بخونید.
اشتراک‌ها
زمان استفاده از IEnumerable, ICollection و IList

من فکر میکنم این سوال که چه زمانی باید از IEnumerable , ICollection , IList استفاده کنیم یک سوال رایج هست که بطور واضح به اون پاسخ داده نشده .

من نه تنها میخوام توی این مقاله این کار رو انجام بدم , بلکه میخوام اطلاعات بیشتری در اختیار شما قرار بدم که به درک عمیق‌تری برسید .

اگر به درک اصل برسید , دفعه‌ی بعد از تصمیمتون مطمئن خواهید بود .

زمان استفاده از IEnumerable, ICollection  و IList