مطالب
خواندنی‌های 8 مرداد
نظرات مطالب
EF Code First #13
در این روش چطوری می‌شه دستور Where رو به صورت یک رشته اجرا نمود
به طور مثال این دستور
DBEntities MyDB = new DBEntities();
        var Query1 = from P in MyDB.Per
        where P.IDRANK == 2
        select P;
تبدیل بشه به یه چنین دستوری
string strquery = "where P.IDRANK == 2";
    DBEntities MyDB = new DBEntities();
    var Query1 = from P in MyDB.Per
         strquery 
    select P;
مطالب
نحوه‌ی استخراج شماره سریال سخت افزار برای تولید یک قفل سخت افزاری
شما در حال نوشتن یک نرم افزار هستید و برای این نرم افزار ممکن است ماه‌ها وقت صرف کرده باشید؛ پس باید به دنبال راهی باشید که بتوانید از آن محافظت کنید. راه‌های متعددی برای Trial کردن نرم افزار وجود دارند که یکی از این راه‌ها استفاده از سریال سخت افزارهای کامپیوتر کاربر است. همانطور که می‌دانید هر سخت افزار یک شماره‌ی سریال مخصوص خودش را دارد و بدین طریق میتوان یک شماره سریال منحصر به فرد را تولید کرد. ما در این مقاله برای بدست آوردن کلیه‌ی مشخصات سخت افزار یک کامپیوتر از کلاس ManagementObjectSearcher در فضای نام System.Management استفاده کرده‌ایم. 
using System.Management;
using System.Windows.Forms;
namespace HardwareSerialNumber
{
    class Program
    {
        static void Main()
        {
            string serialNumber = string.Empty;
            ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_Processor");
            foreach (var o in searcher.Get())
            {
                var query = (ManagementObject)o;

                serialNumber = serialNumber + query["ProcessorId"];
            }
            MessageBox.Show(string.Format("Processor Serial Number :{0}", serialNumber),"Serial Number",MessageBoxButtons.OK,MessageBoxIcon.Exclamation);

        }
    }
}
خوب. حالا به بررسی کدهای بالا می‌پردازیم. در خط 10 یک شیء از کلاس MangementObjectSearcher ایجاد کرده‌ایم . سازنده‌ی این کلاس 2 پارامتر را می‌پذیرد. اولین پارامتر یک رشته می‌باشد CIMV2 . root\\CIMV2 فضای نام پیش فرض مخصوص کوئری‌های WMI می‌باشد و پارامتر دوم کوئری WMI است. عبارت Win32_Processor اشاره به کلاس Win32_processor دارد. این کلاس بیانگر یک کلاس مدیریتی از نوع CIM (مراجعه کنید به اینجا و اینجا ) است. در خط 11 با استفاده از متد Get، تمامی اطلاعات مربوط به Processor را بارگذاری می‌کنیم و سپس فیلد ProcessorId را در یک رشته قرار می‌دهیم. نکته‌ی دیگر اینکه ارجاعی را به فایل System.Managment.Dll به پروژه‌ی خود اضافه کنید.
نتیجه‌ی کد بالا : 

در این آدرس یک کتابخانه که شامل تمامی مثالها می‌باشد قابل در یافت است.

مطالب
پیاده سازی عملیات صفحه بندی (paging) در sql server

در خیلی مواقع ملاحظه میشود که برای نمایش تعدادی از رکوردهای یک جدول در پایگاه داده، کل مقادیر موجود درآن توسط یک دستور select به دست می‌آید و صفحه‌بندی خروجی، به کنترلهای موجود سپرده میشود. اگر پایگاه داده ما دارای تعداد زیادی رکورد باشد، آن موقع است که دچار مشکل می‌شویم. فرض کنید به طور همزمان ۵ نفر (که تعداد زیادی نیستند) از برنامه ما که شامل ۱۰۰۰۰۰ سطر داده میباشد استفاده کنند و در هر صفحه، ۱۰ رکورد نمایش داده شود و صفحه‌بندی ما از نوع معقولی نباشد. در این صورت به جای اینکه با ۵×۱۰ رکورد داده را بارگزاری کنیم، ۵×۱۰۰۰۰۰ رکورد یعنی ۵۰۰۰۰۰ رکورد را برای به دست آوردن ۵۰ رکورد بارگزاری میکنیم. در زیر روشی شرح داده میشود که توسط آن، این سربار اضافه از روی برنامه و سرورهای مربوطه حذف شود. به stored procedure و توضیحات مربوط به آن توجه فرمایید :

CREATE PROCEDURE sp_PagedItems
(
 @Page int,
 @RecsPerPage int
)
AS

-- We don't want to return the # of rows inserted
-- into our temporary table, so turn NOCOUNT ON
SET NOCOUNT ON


--Create a temporary table
CREATE TABLE #TempItems
(
ID int IDENTITY,
Name varchar(50),
Price currency
)


-- Insert the rows from tblItems into the temp. table
INSERT INTO #TempItems (Name, Price)
SELECT Name,Price FROM tblItem ORDER BY Price

-- Find out the first and last record we want
DECLARE @FirstRec int, @LastRec int
SELECT @FirstRec = (@Page - 1) * @RecsPerPage
SELECT @LastRec = (@Page * @RecsPerPage + 1)

-- Now, return the set of paged records, plus, an indiciation of we
-- have more records or not!
SELECT *,
MoreRecords =
(
 SELECT COUNT(*)
 FROM #TempItems TI
 WHERE TI.ID >= @LastRec
)
FROM #TempItems
WHERE ID > @FirstRec AND ID < @LastRec


-- Turn NOCOUNT back OFF
SET NOCOUNT OFF
در این کد دو پارامتر از نوع integer تعریف میکنیم. اول پارامتر @Page که مربوط به شماره صفحه‌ای می‌باشد که قصد دارید آن‌را بارگزاری نمایید. دومین پارامتر با نام @RecsPerPage تعداد رکوردهایی است که هر بار میخواهید بارگزاری شوند. مثلا اگر میخواهید هر بار ۱۵ عدد از رکوردها را نمایش دهید، این مقدار را باید برابر ۱۵ قرار دهیم. در مرحله بعد یک جدول موقت با نام #TempItems ساخته شده است که به طور موقت مقادیری را در حافظه نگه میدارد. نکته کلیدی که جلوتر از آن استفاده شده، ستون با نام ID است که از نوع auto-increment بوده و روی جدول موقت تعریف شده است. این ستون شناسه هر سطر را در خود نگه میدارد که به صورت اتوماتیک بالا میرود و جزء لاینفکی از این نوع paging میباشد. پس از آن جدول موقت را توسط رکوردهای جدول واقعی با نام tblItem توسط دستور select پر میکنیم.

در مرحله بعد شماره اولین و آخرین سطر مورد نظر را بر اساس پارامترهای ورودی محاسبه کرده و در متغیرهای @FirstRec و @LastRec می‌ریزیم.
برای استفاده از این کد فقط کافیست که پارامترهای ورودی را مقداردهی نمایید. مثلا اگر میخواهید در یک کنترل Grid از آن استفاده کنید باید ابتدا یک کوئری داشته باشید که تعداد کل سطرها را به شما بدهد و بر اساس این مقدار تعداد صفحات مورد نظر را به دست آورید. پس از آن با کلیک روی هر کدام از شماره صفحات آن را به عنوان مقدار به پارامتر مورد نظر بفرستید و از آن لذت ببرید. 

مطالب
React 16x - قسمت 3 - بررسی پیشنیازهای جاوا اسکریپتی - بخش 2
در قسمت قبل، بخشی از تازه‌های ES6 را که بیشتر در برنامه‌های مبتنی بر React مورد استفاده قرار می‌گیرند، بررسی کردیم. در این قسمت نیز سایر موارد مهم باقیمانده را بررسی می‌کنیم.

در اینجا نیز برای بررسی ویژگی‌های جاوا اسکریپت مدرن، یک پروژه‌ی جدید React را ایجاد می‌کنیم.
> create-react-app sample-03
> cd sample-03
> npm start
سپس تمام کدهای داخل index.js را نیز حذف می‌کنیم. اکنون تمام کدهای خالص جاوا اسکریپتی خود را داخل این فایل خواهیم نوشت.
همچنین چون در این قسمت خروجی UI نخواهیم داشت، تمام خروجی را در کنسول developer tools مرورگر خود می‌توانید مشاهده کنید (فشردن دکمه‌ی F12).


متد Array.map

در برنامه‌های مبتنی بر React، از متد Array.map برای رندر لیست‌ها استفاده می‌شود و نمونه‌های بیشتری از آن‌را در قسمت‌های بعدی مشاهده خواهید کرد.
فرض کنید آرایه‌ای از رنگ‌ها را داریم. اکنون می‌خواهیم لیستی را به صورت <li>color</li> به ازای هر آیتم آن، تشکیل دهیم:
const colors = ["red", "green", "blue"];
برای این منظور می‌توان از متد map بر روی این آرایه به نحو زیر استفاده کرد:
const items = colors.map(function(color) {
  return "<li>" + color + "</li>";
});
console.log(items);
متد map یک callback function را دریافت می‌کند که با هر بار فراخوانی آن، یک عنصر از عناصر آرایه را دریافت کرده، آن‌را تغییر شکل داده و بازگشت می‌دهد (چیزی شبیه به متد Select در LINQ).
این مثال را توسط arrow functions نیز می‌توان بازنویسی کرد:
const items2 = colors.map(color => "<li>" + color + "</li>");
console.log(items2);
ابتدا function را حذف می‌کنیم. سپس { return } را تبدیل به یک <= خواهیم کرد. چون تک پارامتری است، نیازی به ذکر پرانتز color وجود ندارد. همچنین نیازی به ذکر سمی‌کالن انتهای return هم نیست؛ چون کل بدنه‌ی این تابع، یک سطر return بیشتر نیست.

یک مرحله‌ی دیگر هم می‌توانیم این قطعه کد را زیباتر کنیم؛ جمع زدن رشته‌ها در ES6 معادل بهتری پیدا کرده‌است که template literals نام دارد:
const items3 = colors.map(color => `<li>${color}</li>`);
console.log(items3);
در اینجا بجای ' و یا " از حرف back-tick استفاده می‌شود. سپس قالب کلی رشته‌ی خود را مشخص می‌کنیم و جائیکه قرار است متغیری را درج کنیم، از {}$ استفاده می‌کنیم که بسیار شبیه به ویژگی string interpolation در #C است. فقط برخلاف آن، حرف $ در ابتدای رشته قرار نمی‌گیرد و باید دقیقا پیش از متغیر مدنظر تعریف شود.


Object Destructuring

فرض کنید شیء آدرس را به صورت زیر تعریف کرده‌ایم:
const address = {
  street: "street 1",
  city: "city 1",
  country: "country 1"
};
اکنون می‌خواهیم خواص آن‌را به متغیرهایی نسبت دهیم. یک روش متداول آن به صورت زیر است:
const street1 = address.street;
const city1 = address.city;
const country1 = address.country;
برای کاهش این حجم کد تکراری که با .address شروع می‌شود، می‌توان از ویژگی Object Destructuring استفاده کرد:
const { street, city, country } = address;
این تک سطر، دقیقا با سه سطر قبلی که نوشتیم، عملکرد یکسانی دارد. ابتدا متغیرهای مدنظر، داخل {} قرار می‌گیرند و سپس کل شیء آدرس به آن‌ها نسبت داده خواهد شد.
در اینجا باید نام متغیرهای تعریف شده با نام خواص شیء آدرس یکی باشند. همچنین ذکر تمامی این متغیرها نیز ضرورتی ندارد و برای مثال اگر فقط نیاز به street بود، می‌توان تنها آن‌را ذکر کرد.
اگر خواستیم نام متغیر دیگری را بجای نام خواص شیء آدرس انتخاب کنیم، می‌توان از یک نام مستعار ذکر شده‌ی پس از : استفاده کرد:
const { street: st } = address;
console.log(st);


Spread Operator

فرض کنید دو آرایه‌ی زیر را داریم:
const first = [1, 2, 3];
const second = [4, 5, 6];
و می‌خواهیم آن‌ها را با هم ترکیب کنیم. یک روش انجام اینکار توسط متد concat آرایه‌ها است:
const combined = first.concat(second);
console.log(combined);

در ES6 با استفاده از عملگر ... که spread نیز نام دارد، می‌توان قطعه کد فوق را به صورت زیر بازنویسی کرد:
 const combined2 = [...first, ...second];
console.log(combined2);
ابتدا یک آرایه‌ی جدید را ایجاد می‌کنیم. سپس تمام عناصر اولین آرایه را در آن گسترده می‌کنیم و بعد از آن، تمام عناصر دومین آرایه را.

شاید اینطور به نظر برسد که بین دو راه حل ارائه شده آنچنانی تفاوتی نیست. اما مزیت قطعه کد دوم، سهولت افزودن المان‌های جدید، به هر قسمتی از آرایه است:
 const combined2 = [...first, "a", ...second, "b"];
console.log(combined2);

کاربرد دیگر عملگر spread امکان clone ساده‌ی یک آرایه‌است:
const clone = [...first];
console.log(clone);

به علاوه امکان اعمال آن به اشیاء نیز وجود دارد:
const firstObject = { name: "User 1" };
const secondObject = { job: "Job 1" };
const combinedObject = { ...firstObject, ...secondObject, location: "Here" };
console.log(combinedObject);
در اینجا تمام خواص شیء اول و دوم با هم ترکیب و همچنین یک خاصیت اختیاری نیز ذکر شده‌است. خروجی نهایی آن چنین شیءای خواهد بود:
 {name: "User 1", job: "Job 1", location: "Here"}

و امکان clone اشیاء توسط آن هم وجود دارد:
const clonedObject = { ...firstObject };
console.log(clonedObject);


کلاس‌ها در ES 6

قطعه کد کلاسیک زیر را که کار ایجاد اشیاء را در جاوا اسکریپت انجام می‌دهد، در نظر بگیرید:
const person = {
  name: "User 1",
  walk() {
    console.log("walk");
  }
};

const person2 = {
  name: "User 2",
  walk() {
    console.log("walk");
  }
};
ابتدا یک شیء person را با دو عضو، ایجاد کرده‌ایم. اکنون برای ایجاد یک شیء person دیگر، باید دقیقا همان قطعه کد را تکرار کنیم. به همین جهت برای حذف کدهای تکراری، نیاز به قالبی برای ایجاد اشیاء داریم و اینجا است که از کلاس‌ها استفاده می‌شود:
class Person {
  constructor(name) {
    this.name = name;
  }

  walk() {
    console.log("walk");
  }
}
برای تعریف یک کلاس ES6، با واژه‌ی کلیدی class شروع می‌کنیم. نام یک کلاس با حروف بزرگ شروع می‌شود (pascal case) و اگر برای نمونه این نام قرار است دو قسمتی باشد، به مانند CoolPerson عمل می‌کنیم. در مرحله‌ی بعد، متد walk را از تعریف شیء شخص، به کلاس شخص انتقال داده‌ایم. سپس متد ویژه‌ی constructor را در اینجا تعریف کرده‌ایم. توسط آن زمانیکه یک نمونه از این کلاس ساخته می‌شود، پارامتری را دریافت و به یک خاصیت جدید در آن کلاس که توسط this.name تعریف شده‌است، انتساب می‌دهیم.
باید دقت داشت که  class Person تنها یک قالب است و const person ای که پیشتر تعریف شد، یک شیء. برای اینکه از روی قالب تعریف شده‌ی Person، یک شیء را ایجاد کنیم، به صورت زیر توسط واژه‌ی کلیدی new عمل می‌شود:
const person3 = new Person("User 3");
console.log(person3.name);
person3.walk();
در اینجا اگر دقت کنید، عبارت Person("User 3") شبیه به فراخوانی یک متد است. این متد دقیقا همان متد ویژه‌ی constructor ای است که تعریف کردیم. اکنون توسط شیء person3، می‌توان به خاصیت name و یا متد walk آن دسترسی یافت.

یک نکته: در جاوا اسکریپت، کلاس‌ها نیز شیء هستند! از این جهت که کلاس‌ها در جاوا اسکریپت صرفا یک بیان نحوی زیبای تابع constructor هستند و توابع در جاوا اسکریپت نیز شیء می‌باشند!


ارث بری کلاس‌ها در ES6

فرض کنید می‌خواهیم کلاس Teacher را به نحو زیر تعریف کنیم:
class Teacher {
  teach() {
    console.log("teach");
  }
}
این کلاس دارای متد teach است؛ اما تمام معلم‌ها باید بتوانند راه هم بروند. همچنین قصد نداریم متد walk کلاس Person را هم با توجه به اینکه Teacher یک Person نیز هست، در اینجا تکرار کنیم. یک روش حل این مشکل، استفاده از ارث‌بری کلاس‌ها است که با افزودن extends Person به نحو زیر میسر می‌شود:
class Teacher extends Person {
  teach() {
    console.log("teach");
  }
}
پس از این تعریف، اگر بخواهیم توسط واژه‌ی کلیدی new، یک شیء را بر اساس این کلاس تهیه کنیم، در VSCode، تقاضای ثبت یک سازنده نیز می‌شود:


علت اینجا است که کلاس Teacher، نه فقط متد walk کلاس Person را به ارث برده‌است، بلکه سازنده‌ی آن‌را نیز به ارث می‌برد:
const teacher = new Teacher("User 4");
اکنون می‌توان با استفاده از شیء معلم ایجاد شده، نه فقط به متدهای کلاس Teacher دسترسی یافت، بلکه امکان دسترسی به خواص و متدهای کلاس پایه‌ی Person نیز در اینجا وجود دارد:
console.log(teacher.name);
teacher.teach();
teacher.walk();

در ادامه فرض کنید علاوه بر ذکر نام، نیاز به ذکر مدرک معلم نیز در سازنده‌ی کلاس وجود دارد:
class Teacher extends Person {
  constructor(name, degree) {}
در این حالت اگر به کنسول توسعه دهنده‌های مرورگر مراجعه کنید، خطای زیر را مشاهده خواهید کرد:
 Uncaught ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor
عنوان می‌کند که نیاز است متد ویژه‌ی super را در سازنده‌ی سفارشی کلاس Teacher فراخوانی کنیم. در ES6، فراخوانی سازنده‌ی کلاس پایه، در سازنده‌های سفارشی کلاس‌های مشتق شده‌ی از آن، اجباری است:
class Teacher extends Person {
  constructor(name, degree) {
    super(name);
    this.degree = degree;
  }

  teach() {
    console.log("teach");
  }
}
با اینکار، مقدار دهی خاصیت name کلاس پایه نیز صورت خواهد گرفت. در اینجا همچنین تعریف خاصیت جدید degree و مقدار دهی آن‌را نیز مشاهده می‌کنید. در ادامه باید این پارامتر دوم سازنده را نیز در حین نمونه سازی از کلاس Teacher تعریف کنیم:
const teacher = new Teacher("User 4", "MSc");

در برنامه‌های React، هر زمانیکه یک کامپوننت جدید تعریف می‌شود، کلاس آن، از کلاس پایه‌ی کامپوننت، ارث بری خواهد کرد. به این ترتیب می‌توان به تمام امکانات این کلاس پایه، بدون نیاز به تکرار آن‌ها در کلاس‌های مشتق شده‌ی از آن، دسترسی یافت.


ماژول‌ها در ES 6

تا اینجا اگر مثال‌ها را دنبال کرده باشید، تمام آن‌ها را داخل همان فایل index.js درج کرده‌ایم. به این ترتیب کم کم دارد مدیریت این فایل از دست خارج می‌شود. امکان تقسیم کدهای index.js به چندین فایل، مفهوم ماژول‌ها را در ES6 تشکیل می‌دهد. برای این منظور قصد داریم هر کلاس تعریف شده را به یک فایل جداگانه که ماژول نامیده می‌شود، منتقل کنیم. از کلاس Person شروع می‌کنیم و آن‌را به فایل جدید person.js و کلاس Teacher را به فایل جدید teacher.js منتقل می‌کنیم.
البته اگر از افزونه‌های VSCode استفاده می‌کنید، اگر کرسر را بر روی نام کلاس قرار دهید، یک آیکن لامپ مانند ظاهر می‌شود. با کلیک بر روی آن، منویی که شامل گزینه‌ی move to a new file هست، برای انجام ساده‌تر این عملیات (ایجاد یک فایل جدید js، سپس انتخاب و cut کردن کل کلاس و در آخر کپی کردن آن در این فایل جدید) پیش‌بینی شده‌است.

هرچند این عملیات تا به اینجا خاتمه یافته به نظر می‌رسد، اما نیاز به اصلاحات زیر را نیز دارد:
- هنگام کار با ماژول‌ها، اشیاء تعریف شده‌ی در آن به صورت پیش‌فرض، خصوصی و private هستند و خارج از آن‌ها قابل دسترسی نمی‌باشند. به این معنا که class Teacher ما که اکنون در یک ماژول جدید قرار گرفته‌است، توسط سایر قسمت‌های برنامه قابل مشاهده و دسترسی نیست.
- برای public تعریف کردن یک کلاس تعریف شده‌ی در یک ماژول، نیاز است آن‌را export کنیم. انجام این کار نیز ساده‌است. فقط کافی است واژه‌ی کلیدی export را به پیش از class اضافه کنیم:
 export class Teacher extends Person {
- اگر افزونه‌ی eslint را نصب کرده باشید، اکنون در فایل یا ماژول جدید teacher.js، زیر کلمه‌ی Person خط قرمز کشیده‌است و عنوان می‌کند که کلاس Person را نمی‌شناسد:


برای رفع این مشکل، باید این وابستگی را import کرد:
import { Person } from "./Person";

export class Teacher extends Person {
در اینجا شیء Person، از فایل محلی واقع شده‌ی در پوشه‌ی جاری Person.js تامین می‌شود. نیازی به ذکر پسوند فایل در اینجا نیست.

- مرحله‌ی آخر، اصلاح فایل index.js است؛ چون اکنون تعاریف Person و Teacher را نمی‌شناسد.
import { Person } from "./Person";
import { Teacher } from "./Teacher";
دو سطر فوق را نیز به ابتدای فایل index.js اضافه می‌کنیم تا بتوان new Person و new Teacher نوشته شده‌ی در آن‌را کامپایل کرد.


Exportهای پیش‌فرض و نامدار در ES6

اشیاء تعریف شده‌ی در یک ماژول، به صورت پیش‌فرض private هستند؛ مگر اینکه export شوند. برای مثال export class Teacher و یا export function xyz. به این‌ها named exports گویند. حال اگر ماژول ما تنها یک شیء عمومی شده را داشت (کلاس‌ها هم شیء هستند!)، می‌توان از واژه‌ی کلیدی default نیز در اینجا استفاده کرد:
 export default class Teacher extends Person {
پس از این دیگر نیازی به ذکر {} در حین import چنین شیءای نخواهد بود:
 import Teacher from "./Teacher";

در ادامه اگر یک export نامدار دیگر را به این ماژول اضافه کنیم (مانند تابع testTeacher):
import { Person } from "./Person";

export function testTeacher() {
  console.log("Test Teacher");
}

export default class Teacher extends Person {
نحوه‌ی import آن به صورت زیر تغییر می‌کند:
 import Teacher, { testTeacher } from "./Teacher";
یک default export و یک named export را در اینجا داریم که اولی بدون {} و دومی با {} تعریف شده‌است. این الگویی است که در برنامه‌های React زیاد دیده می‌شود؛ مانند:
import React, { Component } from 'react';

یک نکته: اگر در VSCode داخل {}، دکمه‌های ctrl+space را فشار دهید، می‌توانید منوی exportهای ماژول تعریف شده را مشاهده کنید.


کدهای کامل این قسمت را از اینجا می‌توانید دریافت کنید: sample-03.zip
نظرات مطالب
پرسش و پاسخ‌های متداول ایجاد یک وبلاگ بلاگری
امااز پیامی که میده چنین چیزی فهمیده نمیشه:
The feed address you entered is password protected. You can specify a username and password in the URL like http://user:password@www.website.com/index.xml.
نظرات مطالب
شروع به کار با EF Core 1.0 - قسمت 11 - بررسی رابطه‌ی Self Referencing

با اجرای این کوئری خاص به همراه AsNoTrackingWithIdentityResolution خطای زیر مشاهده می‌شود و اصلا کار نمی‌کند (چون فیلد JSON هم دارد):

System.InvalidOperationException: Invalid token type: 'StartObject'.

در EF-Core و در طی طول عمر «یک» Context:

  • اگر یک کوئری معمولی، به همراه Change Tracker گرفته شود، اطلاعات اشیاء بازگشتی از آن، بر اساس ID آن‌ها «کش موقت می‌شوند». اگر در ادامه‌ی همین Context، مجددا این کوئری تکرار شود، این اشیاء مشابه با ID یکسان، نمونه سازی مجدد «نمی‌شوند» (هرچند یکبار دیگر از بانک اطلاعاتی دریافت شده‌اند و این کش موقت، به معنای عدم واکشی اطلاعات از بانک اطلاعاتی نیست) و از همان کش محلی Change Tracker مجددا خوانده می‌شوند.
  • اگر یک کوئری از نوع AsNoTracking گرفته شود، اشیاء بازگشتی از آن، بر اساس ID آن‌ها «کش نمی‌شوند». اگر همین کوئری مجددا در طول عمر Context جاری تکرار شود، نمونه سازی «مجددی» از اشیاء مشابه با ID یکسان را شاهد «خواهیم بود» و EF آن‌ها را از کش موقت Change Tracker جاری، بازیابی مجدد نمی‌کند. بنابراین تکرار این کوئری، مصرف حافظه‌ی بیشتری را به همراه دارد؛ هرچند اگر فقط قرار است یکبار انجام شود (برای انجام یک عملیات گزارشگیری فقط خواندنی)، به دلیل نداشتن سیستم ردیابی، سربار کمتری را از حالت اول دارد.
  • اگر یک کوئری از نوع AsNoTrackingWithIdentityResolution گرفته شود، اشیاء بازگشتی از آن بر اساس ID آن‌ها «کش موقت می‌شوند». اگر همین کوئری مجددا در طول عمر Context جاری تکرار شود، نمونه سازی مجددی از اشیاء مشابه با ID یکسان را شاهد «نخواهیم بود» (هر چند کوئری از بانک اطلاعاتی، داده‌هایی را واکشی کرده‌است)؛ اما وارد سیستم Tracking هم نمی‌شوند و تغییرات بر روی آن‌ها ردیابی نمی‌شوند. به همین جهت این روش در حین تکرار کوئری‌های مشابه در طول عمر یک Context نسبت به AsNoTracking، مصرف حافظه‌ی کمتری دارد.

بنابراین وجود AsNoTrackingWithIdentityResolution فقط در طی طول عمر یک Conetxt و برای کاهش سربار نمونه سازی اشیاء مشابه با IDهای یکسان کوئری‌های آن Context ارزشمند است و اگر Context شما از چندین کوئری مشابه تشکیل نمی‌شود، عملا کار بیشتری را انجام نمی‌دهد و تفاوتی با AsNoTracking ندارد.

نظرات مطالب
EF Code First #10
در EF یک سری متد وجود دارند که حجم کوئری‌های LINQ نوشته شده را کاهش می‌دهند. یک نمونه آن Include است، نمونه دیگر استفاده از خواص راهبری است: (^ و ^)
نظرات مطالب
فعال سازی سطح دوم کش در Fluent NHibernate
سلام آقای نصیری
var q1 = session.QueryOver().Where(x => x.Id > 3).Cacheable().List();
var q2 = session.QueryOver().Where(x => x.Id == 4).List();
چرا با اینکه نتیجه کوئری دوم در کوئری اول وجود داره اما باز به دیتابیس مراجعه می کنه؟