PDA

View Full Version : مقاله: بهره بردن از مزیت Enum ها در Entity Framework June 2011 CTP



amirjalili
یک شنبه 06 شهریور 1390, 12:27 عصر
با سلام ,
امروز می خواهیم راجع به قابلیت استفاده از Enum ها در Entity Framework June 2011 CTP صحبت کنیم.

مقدمه :
حتما تا به حال نیاز پیدا کردید که از Enum ها استفاده کنید و میدونید که مزیت استفاده از این نوع مقادیر چیه و تا چه اندازه به برنامه نویس کمک میکنه و همینطور خیلی هم باعث تمیز تر شدن کد ها میشه.
اگه در مورد این انواع شمارشی اطلاعاتی میخواهید به اینجا (http://msdn.microsoft.com/en-us/library/sbbt4032(v=vs.80).aspx) مراجعه کنید . برای اینکه استفاده مناسب از این بخش بکنید نیاز به دانستن کامل در مورد این نوع ها دارید.
همچنین برای دانلود آخرین ورژن Entity framework به اینجا (http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=26660)مراجعه کنید.
همچنین در این توضیح من برای راحتی و خلاصه نویسی از EF به جای Entity framework استفاده میکنم.
تئوری :
همانطور که میدانید نوع های شمارشی در msdn به عنوان انواعی مجزا شامل مجموعه ای از named constant ها در نظر گرفته شده اند . این تعریف عینا در مورد انواع شمارشی در Entity Framework هم صادق است. انواع شمارشی در EF در conceptual layer موجودند. باید بگوییم که مشابه انواع شمارشی در CLR , انواع شمارشی در EF هم دارای TYPE های underlying هستند برای مثال :
Edm.SByte, Edm.Byte, Edm.Int16, Edm.Int32 or Edm.Int64 with Edm.Int32
همچنین نوع شمارشی میتواند 0 یا بیشتر عضو داشته باشد و در صورتی که مقداری برای عضو ابتدایی مشخص شده باشد مقادیر بعدی بر پایه عضو قبلی مقدار دهی میشوند و در صورت عدم مقدار دهی به اعضا این مقدار به طور پیش فرض صفر در نظر گرفته خواهد شد. تمامی این قوانین برای انواع شمارشی در EF صادق است.
نکته آخر اینکه این نوع شمارشی دارای صفت IsFlags است که نشان میدهد که یک نوع شمارشی میتواند به عنوان مجموعه ای از Flag ها استفاده شود و همچنین معادلی است از صفت [Flags] در تعریف Enum در c# یا vb.net . در حال حاضر این صفت فقط برای code generation استفاده میشود.

تمرین :
حالا که تا حدودی با قابلیت نوع شمارشی در EF آشنا شدید میخواهیم در یک مثال تمرینی شما رو با این قابلیت آشنا کنیم. ما در این مثال برای سادگی فقط از یک موجودیت استفاده میکنیم و بعد از اون شما در صورت نیاز میتونید برای تمرین حالت های پیچیده تری رو ایجاد و استفاده کنید. همچنین ما از روش Model First استفاده میکنیم که در اون در ابتدا نیازی به دیتابیس وجود ندارد. بعد از آماده شدن موجودیت و ساخت دیتابیس ما مقادیر رو در اون میریزیم و بعد تمرین را ادامه خواهیم داد.

آماده کردن مدل :
ویژوال استدیو را باز کرده و پروژه جدید ایجاد کنید. برای مثال پروژه ای از نوع console application.
همچنین مطمئن بشید که در حال استفاده از ورژن جدید EF هستید. برای اطمینان از این منظور روی پروژه خود راست کلیک کرده و مشخصات پروژه رو ببینید و Target framework رو روی Entity Framework June 2011 CTP ست کنید. مثل شکل زیر :
http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-68-19/7522.image001.png

پس از آن روی پروژه راست کلیک کرده و از منوی آیتم جدید و از بخش Data مقدار ADO.NET Data Entity Model انتخاب کنید و نام آن را برای مثال "EnumModel" قرار دهید.
در مرحله بعد از tool box یک موجودیت را روی مدل ایجاد کرده و نام آن را product قرار دهید و فیلد های id, name,category را روی آن بسازید . به طور پیش فرض نوعی به این فیلد ها اختصاص داده خواهد شد.
ما میخواهیم در این مثال category از نوع enum باشد و برای مثال دارای 3 مقدار :
Beverage و Dairy و Condiments
باشد.
برای این منظور روی category راست کلیک کنید و گزینه convert to enum را انتخاب کنید.

http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-68-19/5826.image002.png

نام را CategoryType قرار داده و بعد مقادیر نام برده شده را اضافه کنید.
http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-68-19/6646.image003.png

و پس از آن Ok کنید.
اگر در پنل model browser انواع تایپ ها را ببینید متوجه میشوید که تایپ EnumModel.CategoryType اضافه شده است.
http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-68-19/3404.image004.png
همچنین در همان پنل خواهید دید که فولدری با نام Enum Types وجود دارد که به شما اجازه میدهد که انواع شمارشی را ایجاد کنید. برای اینکار میتوانید راست کلیک کرده و گزینه های موجود را ببینید که یکی از آنها Add Enum Type است.

بررسی مدل :
مدل را با Xml (Text) Editor از گزینه Open With باز کنید. عبارت CSDL content جستجو کنید و تگ های آن را
ببینید. چیزی شبیه به زیر خواهیم داشت :


<EntityType Name="Product">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Type="Int32" Name="Id" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
<Property Type="String" Name="Name" Nullable="false" />
<Property Type="EnumModel.CategoryType" Name="Category" Nullable="false" />
</EntityType>
<EnumType Name="CategoryType" UnderlyingType="Byte">
<Member Name="Beverage" />
<Member Name="Dairy" />
<Member Name="Condiments" />
</EnumType>


اگر با دقت توجه کنید خواهید دید که در فیلد category نوع به نوع EnumModel.CategoryType ارجاع داده شده است.

کد جنریت شده برای مدل :

[EdmEnumTypeAttribute(NamespaceName="EnumModel", Name="CategoryType")]
[DataContractAttribute()]
public enum CategoryType : byte
{
/// <summary>
/// No Metadata Documentation available.
/// </summary>
[EnumMemberAttribute()]
Beverage = 0,

/// <summary>
/// No Metadata Documentation available.
/// </summary>
[EnumMemberAttribute()]
Dairy = 1,

/// <summary>
/// No Metadata Documentation available.
/// </summary>
[EnumMemberAttribute()]
Condiments = 2
}

[EdmScalarPropertyAttribute(EntityKeyProperty=false , IsNullable=false)]
[DataMemberAttribute()]
public CategoryType Category
{
get
{
return _Category;
}
set
{
OnCategoryChanging(value);
ReportPropertyChanging("Category");
_Category = (CategoryType)StructuralObject.SetValidValue((byte )value, "Category");
ReportPropertyChanged("Category");
OnCategoryChanged();
}
}
private CategoryType _Category;
partial void OnCategoryChanging(CategoryType value);
partial void OnCategoryChanged();

همانطور که مشاهده میکنید CategoryType به صورت نوع شمارشی و با فیلد های مورد نظر تعریف شده است.

ساخت دیتابیس :
برای تعریف دیتابیس روی مدل کلیک راست کرده و گزینه Generate Database from Model را انتخاب کرده و مقادیر کانکشن استرینگ و دیتابیس اولیه ای که ساخته اید را انتخاب کرده و در نهایت Finish کنید. کدی به صورت کوئری های SQL برای شما جنریت خواهد شد. آن را روی SQL , اجرا کنید تا دیتابیس کامل و منطبق با مدل شما ساخته شود.

بازی با Enum ها :
کلاسی ایجاد کنید و متدی به صورت زیر تعریف کنید که کار آن اضافه کرده مقادیر در دیتابیس برای موجودیت Product است.


public static void Seed()
{
using (var ctx = new EnumModelContainer())
{
if (!ctx.Products.Any())
{
ctx.AddToProducts(new Product() {
Name = "Milk", Category = CategoryType.Dairy });
ctx.AddToProducts(new Product() {
Name = "Seattle's Rain", Category = CategoryType.Beverage });
ctx.AddToProducts(new Product() {
Name = "Cayenne Pepper", Category = CategoryType.Condiments });
ctx.AddToProducts(new Product() {
Name = "Sour Cream", Category = CategoryType.Dairy });
ctx.AddToProducts(new Product() {
Name = "Chevy Volt", Category = (CategoryType)255 });
ctx.SaveChanges();
}
}
}

کد بسیار واضح است و نیازی به توضیح بیشتر نیست.
متد دیگری برای دریافت و چاپ مقادیر product به صورت زیر بنویسید.


public static void DisplayProducts(IEnumerable<Product> products)
{
Console.WriteLine("Products");
foreach (var p in products)
{
Console.WriteLine("Id: {0}, Name: {1}, Category: {2}", p.Id, p.Name, p.Category);
}
}

خوب حالا در Main به صورت زیر متد ها را اجرا کنید.


static void Main(string[] args)
{
classname. Seed();

using (var ctx = new EnumModelContainer())
{
classname.DisplayProducts(ctx.Products);
}
}

پس از اجرا نتایج زیر را مشادهده خواهید کرد :

Products
Id: 1, Name: Milk, Category: DairyProducts
Id: 1, Name: Milk, Category: Dairy
Id: 2, Name: Seattle's Rain, Category: Beverage
Id: 3, Name: Cayenne Pepper, Category: Condiments
Id: 4, Name: Sour Cream, Category: Dairy
Id: 5, Name: Chevy Volt, Category: 255
Press any key to continue . . .


خوب همانطور که دیدید نوع شمارشی شما به خوبی در حال پاسخگویی به نیاز شماست. حالا کمی جلوتر میرویم و کمی عملی تر با انواع شمارشی رو در رو میشویم.
متد Main رو به صورت زیر تغییر دهید :

static void Main(string[] args)
{
classname.Seed();

using (var ctx = new EnumModelContainer())
{
var q = from p in ctx.Products
where p.Category == CategoryType.Dairy
select p;

classname.DisplayProducts(q);
}
}

خوب . نتایج زیر را خواهید داشت.

Products
Id: 1, Name: Milk, Category: Dairy
Id: 4, Name: Sour Cream, Category: Dairy
Press any key to continue . . .


همانطور که مشاهده کردید به راحتی میتوانید از انواع شمارشی در Entity Framework June 2011 CTP استفاده کنید و در جهت اهداف خود آنها را بکار ببرید.
نکته کوچک اما مهم بعدی که وجود دارد استفاده از این نوع شمارشی در موجودیت های درون کد C SHARP شماست. برای اینکار باید فیلد Category از موجودیت Product را از نوع شمارشی موجود در EF که در این مثال CategoryType است و قبلا ساخته اید قرار دهید. به اینصورت شما میتوانید مقادیر در یافتی را به موجودیت های متناظر در کد خود انتقال دهید.

موفق باشید

amirjalili
یک شنبه 06 شهریور 1390, 15:35 عصر
از مدیران عزیز خواهش میکنم این مقاله رو به بخش مقالات منتقل کنند تا این تایپیک که برای بسیاری میتونه مفید باشه در انبوه تایپیک های این بخش گم و گور نشه.
با تشکر