تا قبل از EF 6 برای طراحی یک سیستم عمومی تغییر مقادیر ثبت شده در بانک اطلاعاتی، میشد با استفاده از امکانات توکار Trackingآن، مقادیر تغییر کرده را یافت و برای مثال ی و ک آنها را پیش از درج در بانک اطلاعاتی، یک دست کرد. در EF 6 با معرفی یک سری interceptor میتوان به مراحل پیش و پس از اجرای کوئریها دسترسی پیدا کرد. عمدهترین کاربرد آن، لاگ کردن SQLهای تولیدیو نوشتن برنامههایی شبیه به EF Profiler است. اما ... استفادهی دیگری را نیز میتوان از IDbCommandInterceptor جدید آن تدارک دید: دستکاری SQL تولیدی توسط آن پیش از اعمال به بانک اطلاعاتی.
طراحی یک Interceptor برای یک دست سازی ی و ک
در اینجا کدهای کلاس YeKeInterceptor را ملاحظه میکنید. در متدهایی که به کلمهی Executing ختم میشوند، میتوان به دستورات SQL تولید شده توسط EF، پیش از اعمال بر روی بانک اطلاعاتی دسترسی داشت:
DbCommand، حاوی تمام اطلاعاتی است که به آن نیاز داریم؛ شامل CommandText یا همان SQL تولید شده و همچنین command.Parameters برای دسترسی به مقادیر پارامترهای کوئری. نکتهی مهم تمام این موارد، قابل ویرایش بودن آنها است.
در اینجا پیاده سازی متد الحاقی ApplyCorrectYeKe را که در کلاس YeKeInterceptor مورد استفاده قرار گرفت، ملاحظه میکنید.
در آن، CommandText و همچنین parameter.Valueها در صورت رشتهای بودن، اصلاح میشوند.
سربار این روش نسبت به روشهای پیشیناستفاده از Reflection کمتر است. همچنین اشیاء پیچیده و تو در تو را نیز بهتر پشتیبانی میکند؛ چون در مرحله Executing، کار پردازش این اشیاء پایان یافته و SQL خام نهایی آن در اختیار ما است.
نحوهی استفاده از YeKeInterceptor
در آغاز برنامه، سطر زیر را فراخوانی کنید:
یک مثال کامل برای دریافت
Sample32.cs
طراحی یک Interceptor برای یک دست سازی ی و ک
در اینجا کدهای کلاس YeKeInterceptor را ملاحظه میکنید. در متدهایی که به کلمهی Executing ختم میشوند، میتوان به دستورات SQL تولید شده توسط EF، پیش از اعمال بر روی بانک اطلاعاتی دسترسی داشت:
public class YeKeInterceptor : IDbCommandInterceptor { public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext) { command.ApplyCorrectYeKe(); } public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext) { } public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext) { command.ApplyCorrectYeKe(); } public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext) { } public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext) { } public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext) { command.ApplyCorrectYeKe(); } }
public static class YeKe { public const char ArabicYeChar = (char)1610; public const char PersianYeChar = (char)1740; public const char ArabicKeChar = (char)1603; public const char PersianKeChar = (char)1705; public static string ApplyCorrectYeKe(this object data) { return data == null ? null : ApplyCorrectYeKe(data.ToString()); } public static string ApplyCorrectYeKe(this string data) { return string.IsNullOrWhiteSpace(data) ? string.Empty : data.Replace(ArabicYeChar, PersianYeChar).Replace(ArabicKeChar, PersianKeChar).Trim(); } public static void ApplyCorrectYeKe(this DbCommand command) { command.CommandText = command.CommandText.ApplyCorrectYeKe(); foreach (DbParameter parameter in command.Parameters) { switch (parameter.DbType) { case DbType.AnsiString: case DbType.AnsiStringFixedLength: case DbType.String: case DbType.StringFixedLength: case DbType.Xml: parameter.Value = parameter.Value.ApplyCorrectYeKe(); break; } } } }
در آن، CommandText و همچنین parameter.Valueها در صورت رشتهای بودن، اصلاح میشوند.
سربار این روش نسبت به روشهای پیشیناستفاده از Reflection کمتر است. همچنین اشیاء پیچیده و تو در تو را نیز بهتر پشتیبانی میکند؛ چون در مرحله Executing، کار پردازش این اشیاء پایان یافته و SQL خام نهایی آن در اختیار ما است.
نحوهی استفاده از YeKeInterceptor
در آغاز برنامه، سطر زیر را فراخوانی کنید:
DbInterception.Add(new YeKeInterceptor());
یک مثال کامل برای دریافت
Sample32.cs