یکسان سازی ی و ک دریافتی حین استفاده از NHibernate
اندازه‌ی قلم متن
تخمین مدت زمان مطالعه‌ی مطلب: سه دقیقه



تصویر فوق، یکی از تصویرهایی است که شاید از طریق ایمیل‌هایی تحت عنوان "فقط در ایران!" به دست شما هم رسیده باشد. تصور کاربر نهایی (که این ایمیل را با تعجب ارسال کرده) این است که در اینجا به او گفته شده مثلا "مرتضی" را جستجو نکنید و امثال آن. چون برای او تفاوتی بین ی و ى وجود ندارد. همچنین بکار بردن "اقلامی" هم کمی غلط انداز است و بیشتر ذهن را به سمت کلمه سوق می‌دهد تا حرف.

در ادامه‌ی بحث آلرژی مزمن به وجود انواع "ی" و "ک" در بانک اطلاعاتی (+ و + و +)، اینبار قصد داریم این اطلاعات را به NHibernate بسط دهیم. شاید یک روش اعمال یک دست سازی "ی" و "ک" این باشد که در کل برنامه هر جایی که قرار است update یا insert ایی صورت گیرد، خواص رشته‌ای را یافته و تغییر دهیم. این روش "کار می‌کنه" ولی ایده آل نیست؛ چون حجم کار تکراری در برنامه زیاد خواهد شد و نگهداری آن هم مشکل می‌شود. همچنین امکان فراموش کردن اعمال آن هم وجود دارد.
در NHibernate یک سری EventListener وجود دارند که کارشان گوش فرا دادن به یک سری رخدادها مانند مثلا update یا insert است. این رخدادها می‌توانند پیش یا پس از هرگونه ثبت یا ویرایشی در برنامه صادر شوند. بنابراین بهترین جایی که جهت اعمال این نوع ممیزی (Auditing) بدون بالا بردن حجم برنامه یا اضافه کردن بیش از حد یک سری کد تکراری در حین کار با NHibernate می‌توان یافت، روال‌های مدیریت کننده‌ی همین EventListener ها هستند.

کلاس YeKeAuditorEventListener نهایی با پیاده سازی IPreInsertEventListener و IPreUpdateEventListenerبه شکل زیر خواهد بود:
using NHibernate.Event;

namespace NHYeKeAuditor
{
public class YeKeAuditorEventListener : IPreInsertEventListener, IPreUpdateEventListener
{
// Represents a pre-insert event, which occurs just prior to performing the
// insert of an entity into the database.
public bool OnPreInsert(PreInsertEvent preInsertEvent)
{
var entity = preInsertEvent.Entity;
CorrectYeKe.ApplyCorrectYeKe(entity);
return false;
}

// Represents a pre-update event, which occurs just prior to performing the
// update of an entity in the database.
public bool OnPreUpdate(PreUpdateEvent preUpdateEvent)
{
var entity = preUpdateEvent.Entity;
CorrectYeKe.ApplyCorrectYeKe(entity);
return false;
}
}
}
در کدهای فوق روال‌های OnPreInsert و OnPreUpdate پیش از ثبت و ویرایش اطلاعات فراخوانی می‌شوند (همواره و بدون نیاز به نگرانی از فراموش شدن فراخوانی کدهای مربوطه). اینجا است که فرصت داریم تا تغییرات مورد نظر خود را جهت یکسان سازی "ی" و "ک" دریافتی اعمال کنیم (کد کلاس CorrectYeKe را در پیوست خواهید یافت).

تا اینجا فقط تعریف YeKeAuditorEventListener انجام شده است. اما NHibernate چگونه از وجود آن مطلع خواهد شد؟
برای تزریق کلاس YeKeAuditorEventListener به تنظیمات برنامه باید به شکل زیر عمل کرد:
using System;
using System.Linq;
using FluentNHibernate.Cfg;
using NHibernate.Cfg;

namespace NHYeKeAuditor
{
public static class MappingsConfiguration
{
public static FluentConfiguration InjectYeKeAuditorEventListener(this FluentConfiguration fc)
{
return fc.ExposeConfiguration(configListeners());
}

private static Action<Configuration> configListeners()
{
return
c =>
{
var listener = new YeKeAuditorEventListener();
c.EventListeners.PreInsertEventListeners =
c.EventListeners.PreInsertEventListeners
.Concat(new[] { listener })
.ToArray();
c.EventListeners.PreUpdateEventListeners =
c.EventListeners.PreUpdateEventListeners
.Concat(new[] { listener })
.ToArray();
};
}
}
}
به این معنا که FluentConfiguration خود را همانند قبل ایجاد کنید. درست در زمان پایان کار تنها کافی است متد InjectYeKeAuditorEventListener فوق بر روی آن اعمال گردد و بس (یعنی پیش از فراخوانی BuildSessionFactory).

کدهای NHYeKeAuditor را از اینجا می‌توانید دریافت کنید.

  • #
    ‫۱۳ سال و ۱۰ ماه قبل، یکشنبه ۲۸ آذر ۱۳۸۹، ساعت ۲۳:۰۲
    دست شما درد نکنه.
    اگه امکان داره در مورد NH3 که به تازگی ریلیز شده مطلب بنویسید
  • #
    ‫۱۳ سال و ۱۰ ماه قبل، یکشنبه ۲۸ آذر ۱۳۸۹، ساعت ۲۳:۱۳
    هیچ وقت دنبال این قضیه رو نگرفتم که خود SQL این قضیه رو می‌تونه حل کنه یا نه ولی احتمالاً خود MS باید یک فکری برای این قضیه کرده باشه. شاید با Collation ها!

    شما در این مورد اطلاع دارید؟
  • #
    ‫۱۳ سال و ۱۰ ماه قبل، یکشنبه ۲۸ آذر ۱۳۸۹، ساعت ۲۳:۲۲
    نه. از Collation ها هم کاری ساخته نیست. در این مورد اینجا بیشتر بحث شده : (+)

    ضمنا این رو هم در نظر داشته باشید که بانک اطلاعاتی‌های گوناگونی داریم (فقط SQL Server را نباید مد نظر داشت) و ... هنگام تصمیم‌گیری باید یک راه حل کلی که همانا یکسان سازی دریافتی است را اعمال کرد.
  • #
    ‫۱۳ سال و ۱۰ ماه قبل، دوشنبه ۲۹ آذر ۱۳۸۹، ساعت ۰۱:۳۵
    بله مسلماً من در اینجا به SQL به عنوان نمونه اشاره کردم کما اینکه اکثر DBهای مدرن از چیزی شبیه این پشتیبانی می‌کنند.
  • #
    ‫۱۳ سال و ۱۰ ماه قبل، دوشنبه ۲۹ آذر ۱۳۸۹، ساعت ۰۲:۱۸
    بله. Collation نحوه‌ی ذخیره سازی و همچنین مرتب سازی و مقایسه‌ی اطلاعات رشته‌ای را مشخص می‌کند (کاری با تاریخ ندارد).
    اما چندتا بحث هست. Collation های فعلی یا Collation های آتی.
    مدل توسعه‌ی SQL Server باز نیست. به این معنا که مثلا تا سال 2008 طول کشید تا Persian Collation به آن اضافه شد (Persian_100_CS_AS ، آن هم فقط با هدف گیری قسمت مرتب سازی صحیح رشته‌ها) یا Collation فعلی SQLite در مرتب سازی یک سری حروف فارسی مشکل دارد (بر اساس کدهای اسکی حروف عمل می‌کند، چیزی که در SQL Server حل شده است به لطف وجود Collation مناسب). البته مدل توسعه‌ی آن باز است ولی ... من ندیم کسی این مورد را اصلاح کند و یک patch ارائه دهد.
    هنوز کسی در مورد قسمت و مفهوم مقایسه‌ای رشته‌ها در Collations کاری نکرده است که جای کار دارد (مثلا ی و ى یکی درنظر گرفته شود).
    ولی باز هم به عنوان راه حل جامع قابل قبول نیست. چون گیرم به نگارش بعدی اضافه شد، نگارش‌های قبلی چه کنند؟ سایر بانک‌های اطلاعاتی چکار کنند؟
    به همین جهت یک راه حل ساده و بدون نیاز به منتظر ماندن و سازگار با تمام بانک‌های اطلاعاتی، یکسان سازی اطلاعات دریافتی است.
  • #
    ‫۱۳ سال و ۱۰ ماه قبل، دوشنبه ۲۹ آذر ۱۳۸۹، ساعت ۱۶:۰۳
    من هم کاری به تاریخ ندارم. فعلاً ما تنهای چیزی که در این زمینه نیاز داریم این است که همانطور که SQL میتواند در هنگام Query گرفتن بین "a" و "A" فرقی نگذارد، برای «ی» و «ی» نیز به همین ترتیب عمل کند.

    البته صحبت شما در مورد نگارش های قبلی بانک‌ها درست است. اما حس می‌کنم این قضیه مانند استفاده از CSS 3.0 خواهد شد. این چیزی است که نبود آن برای یک Database مدرن یک کمبود واقعیست. البته من سعی خواهم کرد در Connect.Microsoft این مورد را گزارش دهم. مثلا یک Collation به نام "Perisan_X_CI_AI_YI_KI" دیده شود که:
    YI: Yeh Insesitive
    KI: Keh Insensitive
    مثلاً !!!

    ظاهراً مایکروسافت _حداقل بیشتر از غول‌های دیگر_ به زبان ما و شبیه آن اهمیت می‌دهد.
  • #
    ‫۱۳ سال و ۱۰ ماه قبل، دوشنبه ۲۹ آذر ۱۳۸۹، ساعت ۱۶:۰۷
    اتفاقا اضافه شدن Persian_100_CS_AS هم بر اساس پیگیری کاربران ایرانی بوده؛ بنابراین این نوع نامه نگاری‌ها واقعا تاثیر دارد و اهمیت می‌دهند.
  • #
    ‫۱۳ سال و ۱۰ ماه قبل، دوشنبه ۲۹ آذر ۱۳۸۹، ساعت ۲۲:۱۸
    سلام مهندس
    برای Update عمل نمی کنه!!!
  • #
    ‫۱۳ سال و ۱۰ ماه قبل، دوشنبه ۲۹ آذر ۱۳۸۹، ساعت ۲۲:۵۲
    مایکروسافت مورد مشابهی در مورد الف و همزه برای عربی زبان‌ها دارد که مشابه اون رو می‌شه برای ی/ی ک/ک ما هم می‌شه درخواست داد.
    در سیستم‌های مدیریت محتوای (غالبن متن‌باز ِ) با پشتیبانی فارسی مقل جوملا و سایر خلنواده‌هاش تبدیل خودکار حروف عربی به فارسی معمولن ساپورت می‌شه و از جمله مثلن یکی از پلاگین‌های پیش‌فرض وردپرس تبدیل خودکار ی/ک به ی/ک هستش.

    + یه موردی که بارها خواسته بودم ازتون سوال کنم و بحثش پیش نیومده بود اینه که شما خودتون از kbdfa عربی پورت شده از روی ویندوز98 هنوز استفاده می‌کنید که "ک" و "ی" عربیه.
    چرا از برنامه‌های زیادی که برای این کار است استفاده نمی‌کنید یا خودتون dll مذکور رو جوری تعییر نمی‌دید که ک و ی هاتون فارسی باشه؟
    یادمه چند سال پیش در جایی صحبت شد و توجیه‌تون این بود که مطالب با ی عربی ایندکس شده توی گوگل بیشتره و این استاندارد رایج وب فارسی هستش. برای اون موقع شاید این مطلب درستی بود ولی الان هر کلمه‌ای که خواستید رو سرچ کنید می‌بینید نتایج جستجوی فارسی‌ش برای "ی/ک" بیشتر از "ی/ک" هستش.
  • #
    ‫۱۳ سال و ۱۰ ماه قبل، سه‌شنبه ۳۰ آذر ۱۳۸۹، ساعت ۰۲:۱۰
    @Ali
    خیلی امیدوار شدم ... :)
    بله. ممنون. این یک باگ در پیاده سازی بود. هنگام استفاده از این گوش فرا دهنده‌ها، تنها به روز رسانی خواص یک موجودیت کافی نیست؛ بلکه باید حالت آن‌را هم به روز کرد تا NHibernate واقعا متوجه شود که چیزی تغییر کرده.
    نسخه‌ی جدید را از همان آدرس قبلی ذکر شده دریافت کنید.
  • #
    ‫۱۳ سال و ۱۰ ماه قبل، سه‌شنبه ۳۰ آذر ۱۳۸۹، ساعت ۰۲:۱۹
    @Payamin
    من چون خودم این kbdfa مخصوص ویندوز 7 64 بیتی رو درست کردم (+)، به همین جهت .... یک نوع علاقه است :)
  • #
    ‫۱۳ سال و ۱۰ ماه قبل، چهارشنبه ۱ دی ۱۳۸۹، ساعت ۱۸:۰۹
    سلام مهندس

    در یکی از مقاله‌های قبلیتون که راجع به همین مبحث ی/ی/ک/ک بود، من کامنتی گذاشتم در مورد مشکلی که بعد از این یکسان سازی در هنگام مرتب کردن سطرهای یک جدول پیش خواهد اومد. در کامنتهای مربوط به این پستتون توضیح داده بودم:
    https://www.dntips.ir/2010/08/wcf-ria-services.html

    بعد متأسفانه دیگه فرصت نشد و بعدشم من فراموش کردم که این مبحث را پیگیری کنم. لطفاٌ تصویر زیر را که توی مدیافایر آپ شده ملاحظه کنید:
    http://www.mediafire.com/imageview.php?quickkey=fnyc6ilu6i6n6ur

    یه جدول ساده‌ست که توی اکسس ۲۰۱۰ ساخته شده و حروف ی/ک/ی/ک در اون وارد شده و بعد با استفاده از خود اکسس (یعنی کلیک بر ستون) مرتب شده. (برای اینکار کوئری نوشته نشده)
    همونطور که در تصویر ملاحظه میکنید بعد از مرتب سازی، ک (فارسی) بعد از ی (عربی) قرار گرفته. این مشکل در اکسس ۲۰۰۳ هم بود ولی اکسس ۲۰۰۷ را در دسترس نداشتم.
    نمیدونم که این مشکل بخاطر سلختار دیتابیسی اکسس به وجود میاد یا اینکه مشکل مربوط به Data Grid اون میشه، ولی در برنامه‌های تجاری دیگه‌ای هم این مشکل را دیده‌‌ام.
    اگر شما این مشکل را بررسی کردید و دلیلی براش پیدا کردید خوشحال میشم نتایج را منتشر کنید.
  • #
    ‫۱۳ سال و ۱۰ ماه قبل، چهارشنبه ۱ دی ۱۳۸۹، ساعت ۲۲:۴۴
    سلام
    کاری که اکسس در اینجا کرده یا SQLite ایی که مثال زدم، مرتب سازی بر اساس کدهای یونیکد این حروف است و کار صحیحی (در بدو امر حداقل) انجام شده: (+)

    کد یونیکد "ک" عربی = 1603
    کد یونیکد "ی" عربی = 1610
    کد یونیکد "ک" فارسی = 1705
    کد یونیکد "ى" فارسی = 1740

    یعنی این مرتب سازی بر اساس منطق ریاضی صحیح است؛ اما بر اساس فرهنگ ایران خیر. به همین جهت توسعه دهنده‌های بانک‌های اطلاعاتی مجبور شده‌اند تا مفهومی به نام Collation را ارائه بدهند که در بالا در مورد آن بحث شد. این Collation دیگر صرفا بر اساس منطق ریاضی کدهای یونیکد حروف، مرتب سازی را انجام نمی‌دهد، بلکه بر اساس ادبیات و فرهنگ زبان‌های مختلف کار مرتب سازی را انجام خواهد داد. SQL Server در این زمینه حداقل برای فارسی زبان‌ها یک Collation مخصوص را در نگارش 2008 خودش ارائه داده تا مرتب سازی صورت گرفته روی رشته‌ها دقیقا مطابق فرهنگ و ادبیات ایرانی باشد (برای سایر کشورها هم این نوع Collation ها پیش بینی شده).
    در اکسس که مد نظر شما است این Collation به نام General Sort order مهیا است (در اکسس‌های جدید در قسمت فایل، options و سپس برگه‌ی general قسمتی هست به نام new database sort order که همین collation است) (+)
    و اگر در این مورد خاص درست کار نمی‌کند باید با مایکروسافت مکاتبه کرد و این مسایل را توضیح داد.
  • #
    ‫۱۳ سال و ۱۰ ماه قبل، پنجشنبه ۲ دی ۱۳۸۹، ساعت ۱۵:۲۲
    سلام و عرض ادب
    اگر کلیت مشکل فارسی و عربی را بررسی کنیم به گمانم به 3 سطح زیر میرسیم
    1- تبدیل در ویندوز
    2- تبدیل در UI
    3- تبدیل در بانک اطلاعاتی

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

    اما در سطح بانک اطلاعاتی بدلیل کنترلهای فراوان و احتمال خطا زیاد موافق نیستم (اگر نیاز است میتوانم توضیح بیشتری بدهم )

    در سطح UI هم همانگونه که فرمودید مشکلات عدیده ایی وجود دارد

    در سطح ویندوز بهترین راه حل است ..اما نمیدانم چگونه میتوانم انرا پیاده کنم . اگر بتوانید راهنمایی بفرمایید من در مورد پیاده سازی و یا سرمایه گذاری روی پیاده سازی مشکلی ندارم

    مرسی

    وکیلی

    Javan_Soft@Yahoo.com
  • #
    ‫۱۳ سال و ۱۰ ماه قبل، پنجشنبه ۲ دی ۱۳۸۹، ساعت ۱۶:۲۶
    سلام، در سطح ویندوز استفاده از kbdfa.dll استاندارد و اصلاح شده کفایت می‌کند (و مزیتی هم که دارد این است که به تمام برنامه‌های موجود به صورت یک دست اعمال می‌شود؛ بدون نیاز به کد نویسی). یعنی اگر این مورد همه‌گیر شود اصلا مشکلی نخواهیم داشت.
    این فایل را هم از اینجا می‌توانید دریافت کنید: (+)
  • #
    ‫۱۳ سال و ۱۰ ماه قبل، پنجشنبه ۲ دی ۱۳۸۹، ساعت ۱۶:۲۹
    اضافه کنم که فایل بالا مریوط به ى و ک فارسی است. اگر ی و ک عربی مد نظر است به این مطلب مراجعه کنید: (+)
  • #
    ‫۱۳ سال و ۱۰ ماه قبل، پنجشنبه ۲ دی ۱۳۸۹، ساعت ۲۱:۵۲
    مرسی از سرعت جواب
    مشکل در این است که این فایل را چگونه در ویندوز 7 بدون مشکل امنیتی نصب کنم
    میدانید که کاربر را نمیتوان در گیر SafeMode و یا پیدا کردن شاخه های ویندوز نمود
    در عین حال هم قبلا برخی از DLLهای موجود در اینترنت را استفاده کرده اما جوابگو نبوده است . امیدوارم این مورد به سرچ من پایان دهد
    باز هم از جوابگویی متشکرم
  • #
    ‫۱۳ سال و ۱۰ ماه قبل، پنجشنبه ۲ دی ۱۳۸۹، ساعت ۲۲:۵۱
    از این نصاب استفاده کنید: (+)
    سپس از قسمت regional settings کنترل پنل، صفحه کلید اضافه شده باید انتخاب شود.
  • #
    ‫۱۳ سال و ۱۰ ماه قبل، یکشنبه ۵ دی ۱۳۸۹، ساعت ۱۵:۲۴
    از برنامه فوق جهت نصب استفاده کردم و صفحه کلید درست شد .(Persian-2901)
    اما در برخی قسمتهای برنامه ام فونت ها بصورت علامت سوال نمایش داده می شود. برای درست شدن علامت سوالها در
    Region-> admin-> Change System local
    Current System Local را به Persian تبدیل کردم . با این کار مشکل علامت سوالها حل شد ولی دوباره ک و ی فارسی به سیستم برگشت . پس از اینکه همین بخش را به English تبدیل کردم دوباره ک و ی عربی را داشتم .

    آیا مشکل علامت سوالها در برخی موارد میتواند بدلیل برنامه نویسی (نسخه دلفی / کامپوننت مورد استفاده و یا ترکیب فونت )باشد ؟
  • #
    ‫۱۳ سال و ۱۰ ماه قبل، یکشنبه ۵ دی ۱۳۸۹، ساعت ۱۶:۱۹
    این مشکلات زمان VB6 (مرحوم) هم بود (مثلا هنگام انتخاب فونت برای یک متن فارسی باید script آن را در صفحه انتخاب فونت روی Arabic گذاشت تا درست نمایش داده شود). قبل از دات نت. قبل از یونیکد شدن رشته‌ها در سیستم‌های متداول دات نت به صورت پیش فرض از نگارش یک آن.
    دلفی‌های جدید هم به نظر رشته یونیکد را پیش فرض خود کرده‌اند (نگارش‌های بعد از 2007). بهتر است برنامه خودتون رو به این نگارش‌ها ارتقاء بدید (تا به صورت خودکار همه چیز منجمله کامپوننت‌ها(ی جدید) بر مبنای رشته‌های یونیکد کار کنند)، همچنین بانک اطلاعاتی هم باید واقعا رشته‌های یونیکد را ساپورت کند. مثلا در SQL Server ، بین نوع‌های varchar و nvarchar تفاوت وجود دارد.
    در کل من با این صفحه کلید و برنامه‌های دات نت، نه مشکلی در ثبت دارم و نه مشکلی در نمایش (چند سال هست). همچنین نیم فاصله هم جهت تایپ فارسی پشتیبانی می‌شود + ساپورت فونت‌های قدیمی هم لحاظ شده.
  • #
    ‫۱۳ سال و ۱۰ ماه قبل، یکشنبه ۵ دی ۱۳۸۹، ساعت ۱۷:۰۱
    البته فرمایش شما صحیح است .این مشکلات قبلا هم وجود داشته است . اما با توجه به اینکه بنده از دلفی 2010 و کامپونتهای استاندار آن استفاده میکنم و کد پیج را هم روی عربیک گذاشته ام فکر میکنم این نظر مشکل داشته باشد .
    با این وجود تست کرده و نتیجه را مجددا خدمت شما اعلام خواهم کرد
    متشکرم
  • #
    ‫۱۳ سال و ۱۰ ماه قبل، دوشنبه ۶ دی ۱۳۸۹، ساعت ۱۶:۰۸
    یک روش ساده پیدا کردم که اگر استاده هم در مورد آن نظر بدهند ممنون میشوم
    پس از نصب ویندوز 7 هیچ نوع فارسی سازی روی آن نصب نکردم .
    تنها در بخش
    Region-> admin-> Change System local
    Current System Local را به Persian تبدیل کردم

    پس از ری استارت ویندوز تمامی علامت سواالها فارسی شد.
    سپس در برنامه ام کد پیج فارسی (عربی)
    LoadKeyboardLayout('00000429', 1) ;
    را لود کردم .

    براحتی کیبوردی که پ و ژ آن صحیح است ارائه شد. ی و ک هم عربی خورد .نیم فاصله هم کاملا صحیح عمل میکند.
    توضیح در مورد ویندوز مورد استفاده ام
    Product Id : 00426-OEM-8992662-00497
    System Type : 32-bit

    در بخش Regional and Language
    Format : English
    Location : United states
    Keyboard : English-US (فقط.هیچ فارسی اضافه نشده )
    System Locale : Persian
  • #
    ‫۱۳ سال و ۱۰ ماه قبل، دوشنبه ۶ دی ۱۳۸۹، ساعت ۱۶:۱۴
    این روش هم برای برنامه‌های دسکتاپ خوبه. ولی بحث اصلی این تاپیک تقریبا به تمام برنامه‌هایی که می‌توانند از NHibernate استفاده کنند و الزاما هم توانایی دخل و تصرف در سیستم را ندارند (مانند برنامه‌های وب)، قابل بسط و استفاده است.