کلاس های Entity Framework CodeFirst در WCF

کلاس های Entity Framework CodeFirst در WCF

کلاس های Entity Framework CodeFirst در WCF

WCF چیست؟

استفاده از کلاس های Entity Framework CodeFirst در WCF  به این معنی است که با WCF  آشنا هستیم ولی به جهت حفظ ساختار مقاله ذکر این نکته ضروری به نظر می رسد: WCF یا Windows Communication Foundation یک فریم ورک سرویس گرا و زیر مجموعه پروژه .net Frametword است. می توان سرویس WCF را در وب سرور IIS هاست کرد. wcf از پروتوکل های مختلفی پشتیبانی می کند از جملع: HTTP, WS-HTTP, TCP, P2P, MSMQ

CodeFirst

مایکروسافت در نسخه Entity Framework 4.1 برای اولین بار کلاس DbContext را معرفی کرد که شیوه نوینی جهت برنامه نویسی برای پایگاه داده بوده و با نام CodeFirst شناخته می شود. این شیوه برنامه نویسی بسیار مورد استقبال برنامه نویسان گرفت و در نسخه های بعدی امکانات جالب فراوانی به آن اضافه شد و هم اکنون نیز در حال توسعه و بهینه سازی می باشد.

یکی از مشکلات کار با ابزار های ORM این است که کلاس های تولید شده معمولا از کلاس های پایه ای به ارث رفته اند و این موضوع باعث می شود که این کلاس ها به سادگی قابل انتقال از سمت سرویس به کلاینت نباشند و هزینه سریالایز (Serialize) و دی سریالایز (Deserialize) نمودن این کلاس ها نیز بسیار بالا است.

به همین دلیل این موضوع همواره مورد علاقه برنامه نویسان بوده است که بتوانند از کلاس های پایه خود (POCO) و بدون هیچ سربار اضافی به جای کلاس های پیش فرض تولید شده توسط Entity Framework استفاده نمایند.

با استفاده از روش CodeFirst براحتی می توان این قابلیت را ایجاد نمود. برای درک بهتر مسئله، به مثال زیر توجه کنید:

فرض کنید که دو کلاس به نام های Customer و Address داریم و به ازای این دو کلاس، دو جدول در پایگاه داده با همین نام ها وجود دارد. رابطه بین جدول Customer با جدول Address از نوع “یک به چند” می باشد یعنی هر مشتری می تواند چندین آدرس داشته باشد.

نمونه کد کلاس های CodeFirst

کلاس های مربوط به این جداول در روش CodeFirst مشابه قطعه کد زیر می باشند:

public partial class CustomerDBEntities : DbContext

{
public DbSet<Address> Addresses { get; set; }
public DbSet<Customer> Customers { get; set; }
}
public class Customer

{
public Customer()
{
this.Addresses = new HashSet<Address>();

}
public int CustomerId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public ICollection<Address> Addresses { get; set; }

}
public class Address

{
public int AddressId { get; set; }
public int CustomerId { get; set; }
public string Street { get; set; }
public string Alley { get; set; }
public int No { get; set; }
public Customer Customer { get; set; }
}

همانطور که در مثال بالا مشاهده می کنید، کلاس های Customer و Address از هیچ کلاس دیگری به ارث نرفته اند و دارای ویژگی های اضافه دیگری نیز نیستند و کاملا مناسب برای منظور ما یعنی استفاده در سرویس های WCF می باشند.

در ورش بالا چند محدودیت برای برنامه نویس ایجاد می شود، از جمله اینکه چون موجودیت ها از کلاس های پایه Entity Framework به ارث نرفته اند، پس قابلیت های Lazy Loading و Change Traking از کار افتاده اند و دیگر قابل استفاده نمی باشند.

Lazy Loading

برای اینکه قابلیت Lazy Loading را برای کلاس ها فراهم کنیم کافیست که خصوصیاتی ناوبری (Navigation Properties) را به شکل virtual در آوریم. لازم به ذکر است که خصوصیاتی ناوبری، همان خصوصیاتی می باشند که نمایانگر ارتباط بین کلاس ها (و احتمالا جداول پایگاه داده) می باشند. در مثال ما هر مشتری می تواند چندین آدرس داشته باشد و هر آدرس حتما مربوط به یک مشتری می باشد. بنابراین خصوصیت Addresses در کلاس Customer و خصوصیت Customer در کلاس Address نمایانگر این رابطه بوده و خصوصیاتی ناوبری می باشند.

تغییرات ما برای کلاس های Customer و Address به شکل زیر اعمال شده است.

public class Customer

{public Customer()
{
this.Addresses = new HashSet<Address>();
}
public int CustomerId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public Vritual ICollection<Address> Addresses { get; set; }

}
public class Address

{
public int AddressId { get; set; }
public int CustomerId { get; set; }
public string Street { get; set; }
public string Alley { get; set; }
public int No { get; set; }
public virtual Customer Customer { get; set; }
}

پروکسی های پویا Dynamic Proxies

شاید این سوال در ذهنتان بوجود آمده باشد که چگونه فقط با اضافه نمودن کلمه کلیدی virtual این قابلیت Lazy Loading به کلاس های ما اضافه می شود؟!

با virtual کردن خصوصیات ناوبری، Entity Framework هنگام اجرای برنامه (RunTime) کلاس هایی با عنوان “پروکسی های پویا” یا همان Dynamic Proxies به کلاس های Address و Customer اضافه می کند و بنابراین قابلیت Lazy Loading برای این کلاس ها در زمان اجرای برنامه فراهم می گردد.

تا اینجای کار توانستیم با تغییر کوچکی در کلاس ها قابلیت Lazy Loading را فراهم کنیم ولی با اضافه شدن پروکسی های پویا به کلاس های ما، مجددا مشکل ابتدای مقاله پدیدار می شوند و این کلاس ها قابلیت انتقال خود از طریق سرویس های WCF را از دست می دهند زیرا پروکسی های پویا به طور پیش فرض قابلیت سریالایز و دیسریالایز شدن را ندارند!

قابلیت Change Tracking

قبل از این که به سراغ راه حل برویم بد نیست به این موضوع نیز اشاره کنیم که در صورتی که تمامی خصوصیات کلاس های خود را virtual کنیم، قابلیت Change Tracking نیز به کلاس های ما اضافه می شود ولی اضافه نمودن این قابلیت بر روی راندمان و کارایی برنامه تاثیر می گذارد.

خوشبختانه با استفاده کلاس DbContext می توانیم تولید کلاس های پروکسی را در زمان اجرای برنامه را فعال یا غیر فعال کنیم. بنابراین تنها کافیست که هر زمان نیاز به استفاده از آن ها در سرویس های WCF داشتیم، این قابلیت را به شکل زیر از کار بیندازیم. در اینصورت قابلیت Lazy Loading و برخی ویژگی های دیگر از کار افتاده و کلاس ها قابلیت استفاده در سرویس های WCF را خواهند داشت.

public Customer GetFirstCustomer()
{ using(var context = new CustomerDBEntities())
{
context.Configuration.ProxyCreationEnabled = false;
var firstCustomer = context.Customers.FirstOrDefault() return firstCustomer;
}
}

در متد بالا ویژگی ProxyCreationEnabled مربوط به کلاس DbContext را غیر فعال نموده ایم و بنابراین پروکسی های داینامیک تولید نخواهند شد و نتیجه کوئری قابل استفاده در سرویس های WCF خواهد بود.

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

مطالب مرتبط:

خرید هاست برای MVC

مدل ویو-ویو مدل MVVM

نکته های فری لنسری یا دورکاری

موارد مهم در طراحی سایت

ساخت کپچا

نصب وردپرس

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *