# برنامه نویسی با محصولات مایکروسافت > برنامه نویسی مبتنی بر Microsoft .Net Framework > مقالات مرتبط با Microsoft .Net Framework >  پیاده سازی Query Notification در ASP.NET

## Behrouz_Rad

*توجه:
کلیه ی حقوق این مقاله متعلق به سایت www.barnamenevis.org است.
نقل از نوشته های این مقاله منوط به ذکر نام منبع است.*

کدهای مرتبط با این مقاله را از انتهای همین پست دانلود کنید.
کدهای برنامه با #C نوشته شده و دیتابیس برنامه، SQL Server 2005 است.

این روش مختص به ASP.NET نیست و فرایند کار در هر زبان برنامه نویسی وب قابل پیاده سازی است.

Query Notification چیست؟
مشکلی که اکثر برنامه نویسان با اون درگیر هستند، بحث همزمانی کار با داده ها توسط کاربران است.
بدین معنا که دو کاربر در یک زمان در حال کار با داده های یکسان و یا داده هایی که با یکدیگر مرتبط هستند می باشند.
روش های مختلفی برای کنترل ناسازگاری ای که در اثر تاثیر تغییر داده ها بر روند پردازش اونها بروز می کنه وجود داره.
در SQL Server 2005 سرویس جدیدی با نام SQL Service Broker معرفی شد که قابلیت جدیدی با نام Query Notification را به برنامه نویسان معرفی نمود.
این سرویس با دریافت یک Query و مانیتور کردن اون بر روی دیتابیس، تحقق شرط Query رو گزارش میده.
به عنوان مثال، شما یک Query مینویسید که در صورت انجام هر گونه تغییری بر روی جدولی خاص از دیتابیس، به برنامه ی کلاینت گزارش داده بشه. وظیفه ی بررسی تحقق شرط Query شما رو Query Notification بر عهده میگیره.
کلاسی که در دات نت به منظور کار با این قابلیت استفاده میشه، کلاس SqlDependency هست که متد Start اش عملیات مانیتورینگ رو آغاز می کنه.
بسیار خوب...
این روش بسیار عالیه اما فقط در برنامه ی های ویندوزی و نه در برنامه های مبتنی بر وب!
در ASP.NET نیز میشه به روشی که در بالا توضیح دادم عمل کرد اما با اندکی تفاوت...
معمولا برنامه نویسان روش فوق رو با تکنیک Caching پیاده سازی می کنند. اگر با مفهوم Caching در ASP.NET آشنا باشید، مطمئنا می دونید که میشه Cache رو به یک دستور SQL وابسته کرد (که با تنظیم پارامتر SqlDependency دایرکتیو OutputCache انجام میشه) تا در صورت تحقق دستور اس کیو ال، Cache غیر فعال بشه.
این روش به هیچ وجه کارامد نیست! از جمله مشکل اصلی در این روش، نیاز به Refresh صفحه در فواصل زمانی مشخص هست و این یعنی یک فاجعه ی بزرگ برای کاربر!
احتمالا کاربر در هر بار Refresh صفحه شما رو نفرین می کنه! ;)
در ادامه روشی رو یاد میگیرید که کارامدی فوق العاده ی داره و بر همگان واجب است که از این روش استفاده کنند!
من عاشق شبیه سازی هستم!... Query Notification رو شبیه سازی می کنیم؛ بدوم اینکه از SQL Service Broker استفاده کنیم یا نیازی به Cache داشته باشیم.

تشریح فرایند کار:
معما: اون چیه که در SQL Server با تحقق یک شرط خاص خود به خود فراخوانی میشه؟!...
درسته! Trigger!
Trigger ای مینویسیم که در هر بار انجام عملیاتی خاص، مقداری تصادفی رو در فیلدی از جدولی که به همین منظور ایجاد کردیم قرار بده.
پس واضح هست که هر بار انجام اون عملیات، Trigger مقدار جدیدی رو در فیلد جدول قرار میده.
این مقدار در بار اول Load صفحه در مکانی (بهترین حالت، کنترل HiddenField هست) نگهداری میشه.
در دفعات بعد، در طی بازه های زمانی مشخصی (با استفاده از AJAX!) این مقدار مجددا بازیابی و با مقدار اولیه مقایسه میشه. اگر برابر بودند، شرط تحقق پیدا نکرده و کاربر با خیال راحت میتونه به کارش ادامه بده؛ در غیر اینصورت، به کاربر پیغامی داده میشه و اون از این مورد آگاه می کنیم و هر رفتاری که دوست داشتید انجام میدید!
روال کار بسیار ساده و در عین حال بسیار کارامد است.

پس روال مانیتور کردن رو با ترکیبی از Trigger و AJAX پیاده سازی می کنیم!

ساختار جداول ساده ست. جدولی که برای نگهداری مقادیر تصادفی ایجاد می کنیم با نام tblNotifications و دارای فیلدهای tblID، TableName و TableRndID هست.
فیلد tblID از نوع  AutoNumber و کلید اصلی ماست.
فیلد TableName نام جدولی رو میگیره که قرار هست Trigger برای اون اجرا بشه.
فیلد TableRndID مقدار تصادفی رو میپذیره و از نوع GUID هست.

جدول دیگه، با نام tblUsers و دارای فیلدهای userID، userFirstName و userFamily هست.

Trigger ای برای جدول tblUsers ایجاد می کنیم تا در هنگام انجام کلیه ی عملیات اضافه، حذف و آپدیت رکورد فراخوانی بشه و مقداری تصادفی رو در فیلد TableRndID جدول tblNotifications قرار بده.
Trigger ما به صورت ذیل هست:

CREATE TRIGGER tgNotificationForTblUsers
ON tblUsers
FOR INSERT, UPDATE, DELETE
AS
UPDATE tblNotifications
WITH (ROWLOCK)
SET TableRndID = NEWID()
WHERE TableName = 'tblUsers'
GO

دو Stored Procedure نیز برای بازیابی اطلاعات کاربران و مقدار تصادفی وجود داره.
کار ما در سطح دیتابیس به پایان رسید.

در کد نویسی Server-Side برنامه، AJAX رو با استفاده از قابلیت جدید ASP.NET 2.0 پیاده سازی کردم. به همین دلیل اگر با نحوه ی استفاده از این قابلیت آشنا نیستید، پیشنهاد می کنم حتما مقاله ی من رو با عنوان " AJAX را بدون AJAX تجربه کنید" مطالعه بفرمایید.
هر چند که تفاوت نمی کنه که به چه شکل از AJAX استفاده می کنید.
UpdatePanel و Ajax Timer نیز جایگزین های خوبی هستند...

کدهای برنامه واضح هست و فکر نمی کنم نیاز به توضیح خاصی وجود داشته باشه.
تنها قسمت مهم، متد GetCallbackResult اینترفیس ICallbackEventHandler هست که در هر بازه ی زمانی مشخص، مقدار تصادفی ذخیره شده در جدول tblNotifications رو بازیابی و به متد جاوا اسکریپت ReceiveDataFromServer در سمت کلاینت پاس میده.
در این متد، مقدار اولیه با مقدار بازیابی شده مقایسه میشه و در صورت متفاوت بودن، به کاربر گزارش داده میشه و از اون خواسته میشه که در صورت تمایل برای مشاهده ی آخرین تغییرات، بر روی دکمه ی OK کلیک کنه.
بازه ی زمانی تعیین شده، پنج ثانیه در نظر گرفته شده و تابع setTimeput در سمت کلاینت وظیفه ی ارسال مداوم درخواست AJAX ای رو بر عهده داره.

دیتابیس برنامه با نام Notification_DB و در پوشه ی App_Data قرار داره. دیتابیس رو در SQL Server 2005 اتچ کنید.
جهت تست برنامه، URL را در دو پنجره ی متفاوت از مرورگر کپی کرده و رکوردی را حذف کنید.
حذف رکورد توسط برنامه تشخیص داده شده و در پنجره ی دیگر به کاربر گزارش داده می شود.

موفق باشید.

----------


## Behrouz_Rad

همچنین برای آگاهی از نحوه ی پیاده سازی Query Notification در برنامه های ویندوزی، میتونید مطلب ذیل رو در وبلاگ بنده مطالعه بفرمایید:
http://brad.barnamenevis.org/?p=23

موفق باشید.

----------


## web developer

با تشکر فراوان از این مقاله خوبتون! :تشویق: 

من میخوام این کارو با SQLserver 2000 انجام بدم ولی نمیشه! فایل های دیتابیس رو نمیشه تو SQL Server 2000 اتچ کرد.

البته دستی این کارو کردم ولی SP ها رو نداشتم.  :ناراحت: 

لطفا اگه میشه راهنمایی کنید.

----------


## Behrouz_Rad

دیتابیس برنامه با SQL Server 2005 ایجاد شده و طبیعیه که شما نمیتونید اون رو به SQL Server 2000 منتقل کنید.

----------


## web developer

> دیتابیس برنامه با SQL Server 2005 ایجاد شده و طبیعیه که شما نمیتونید اون رو به SQL Server 2000 منتقل کنید.


شما اگه دستورات SP هارو برای من بفرستید من بصورت دستی بر روی 2000 پیاده سازی می کنم .

متشکرم

----------


## Mahbadgroup

میشه از SQL Notificaton  توی برنامه application استفاده کنم بطوری که در هنگام تغییر در بانک به یک کلاینت پیام بده؟؟کدی دارید؟؟؟

----------


## Behrouz_Rad

منظورت از "برنامه ی Application" چیه؟ اگر منظورت وب هست که این مقاله در همین مورد صحبت کرده.

----------


## Mahbadgroup

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

----------


## Behrouz_Rad

سوالت ارتباطی با این مقاله نداره. این مقاله مربوط به وب هست. سوالت رو در بخش Win App مطرح کن.

----------


## siaa_98

خوب دوست عزیز. شما گفتید که اشکال کار در sql notificatioin اینه که صفحه مدام باید رفرش بشه و کاربر ما رو نفرین میکنه. چرا اونجا از ajax استفاده نکردید ولی در شبیه سازی خودتون برای فرار از نفرین کاربر، از ajax استفاده کردین؟!!!

----------


## Behrouz_Rad

متوجه نشدم چی گفتی.
فکر می کنم باید یک بار دیگه با دقت مقاله رو مطالعه کنی.

----------


## Behrouz_Rad

متوجه نشدم چی گفتی.
فکر می کنم باید یک بار دیگه با دقت مقاله رو مطالعه کنی.

----------


## ricky22

سلام.
با اینکه تاپیک قدیمی بود اما باید عرض کنم :
این روشن Query Notification را اگر با تکنولوژِ Comet تلفیق کرد زیبا تر می توان پیاده سازی کرد.
با تشکر از آقای راد.

----------


## fakhravari

سلام اقای راد
ممنون بابت سمپل.
اگر بخواهیم 2 یا چنتا جدول برسی کنه به چه شکل است؟
قسمت SQL مشکلی نیست یعنی تریگر و دادن مقادیر به جدول tbNotifications
قسمت کد مشکل دارم
خودم چنتا دستکاری کردم تشخیص هم میداد کدوم جدول بوده اما مسیج تکرار میشد.
سمت کد و جاوا اسکریپت چطوری تنظیم کنم؟

----------


## fakhravari

دوستان کسی نبود. :افسرده:

----------


## fakhravari

دوستان منتظرم

----------


## tarsim

سلام این کد توی پیجی که از مسترپیج ارث برده کار نمیکنه یعنی اون قسمت فرستادن به کلاینتش کار نمیکنه . ولی توی پیجی که از مسترپیج ارث نبرده کار میکنه . به نظر شما مشکل کجاست ؟

----------


## tarsim

کسی نمیدونه چرا ؟

----------

