اگر شغل شما برنامه نویسی هست، حتماً واژه ORM و در کنارش Entity Framework رو شنیدید. يکي از مهمترين ابزار هايي که در نوشتن برنامه هاي Data-Centric استفاده ميشه، ابزار هاي ORM يا Object Relational Mapping هست. اين ابزار ها اين قابليت رو به شما ميدهند که داخل برنامه از بانک اطلاعاتي و جداول داخل اون به صورت Object ها استفاده کنيد. ابزار هاي زيادي در اين مورد وجود دارند که معروف ترين اون ها عبارتند از NHibeate و Entity Framework. در اين مقاله قصد دارم تا در مورد ويژگي Code-First در Entity Framework بنويسم.براي استفاده از اين مقاله ابزار هاي زير مورد نياز هستند:
براي شروع ابتدا Script زير رو داخل Sql Server اجرا کنيد:
CREATE DATABASE Sales;GOCREATE TABLE Sales..ProductCategories( ID INT NOT NULL IDENTITY PRIMARY KEY, Name NVARCHAR(100) NOT NULL);GOCREATE TABLE Sales..Products( ID INT NOT NULL IDENTITY PRIMARY KEY, CategoryID INT NOT NULL REFERENCES Sales..ProductCategories(ID), Name NVARCHAR(100) NOT NULL);GO
بعد از اجراي Script بالا، پروژه اي داخل Visual Studio ايجاد کرده و سپس به Entity Framework يک Reference بدهيد. (براي استفاده از EntityFramework Code First مي تونيد دستور Install-Package EntityFramewokr را که يک دستور NuGet هست اجرا کنيد) حالا بايد داخل پروژه جداول بانک رو به يک سري کلاس Map کنيم. براي اين کار ابتدا کلاس هاي زير را ايجاد کنيد:
public class ProductCategory{ public int ID { get; set } public string Name { get; set; } public virtual ICollection Products { get; set; }}public class Product{ public int ID { get; set; } public ProductCategory Category { get; set; } public int CategoryID { get; set; } public string Name { get; set; }}public class SalesContext : DbContext{ public DbSet ProductCategories { get; set; } public DbSet Products { get; set; }}
همانطور که مشاهده مي کنيد، ما سه کلاس ايجاد کرديم، کلاس هاي ProductCategory، Prduct و SalesContext. دو کلاس اول که کلاس هاي عادي هستند، کلاس آخري يعني SalesContext کار اصلي رو براي ما انجام ميده. يعني وظيفه ارتباط بين کلاس ها و جداول بانک اطلاعاتي رو به عهده خواهد داشت.
داخل کلاس Context ما دو Property ايجاد کرديم. اين Property ها در حقيقت همون جداول ما هستند. حال بايد Coection String بانک رو براي کلاس Context تعريف کنيم. براي اين کار فايل app.config را باز کرده و به صورت زير تغيير مي دهيم:
دقت کنيد که نام CoectionString بايد با نام Context يکي باشد. کل کاري که بايد انجام مي داديم همين بود، حالا مي تونيم از اين کلاس ها داخل برنامه استفاده کنيم. براي مثال، براي اضافه کردن يک ProductCategory بايد به صورت زير عمل کنيم:
SalesContext context = new SalesContext();context.ProductCategories.Add(new ProductCategory() { Name = "Category1" });context.SaveChanges();
با اين کار يک Product Category جديد به بانک ما اضافه خواهد شد. حالا فرض کنيد که مي خواهيم به يک Category يک Product اضافه کنيم، براي اين کار يک سري تغييرات بايد انجام شود. کلاس DbContext يک Virtual Method دارد با نام OnModelCreating که با Override کردن اين متد مي توان عمليات Custom Mapping را انجام داد. در اينجا براي شناساندن Relation بين ProductCategory و Product بايد کد زير را در کلاس SalesContext اضافه کرد:
public override void OnModelCreating(ModelBuilder modelBuilder){ modelBuilder.Entity() .HasMany(category => category.Products) .WithRequired(product => product.Category) .WithForeignKey(product => product.CategoryID);}
با اين کار به کلاس SalesContext مي فهمانيم که کلاس ProductCategory چندين Product دارد که خود Product يک عدد Category داد که بايد حتما" وارد شود که رابطه بين اين دو با کليد خارجي CategoryID مشخص مي شود. (دقت کنيد که در اينجا رابطه ما **-1 يا همان یک به چند است). حالا با اجراي قطعه کد زير مي توان به يک Category يک Product جديد اضافه کرد:
SalesContext context = new SalesContext();var category = context.ProductCategories.Find(1);category.Products.Add(new Product() { Name = "Product1" });context.SaveChanges();دقت کنيد که داخل کلاس ProductCategory، ليست Products بايد از نوع virtual تعريف شود تا Entity Framework بتواند ليست Product ها را هنگام خواندن Category بارگذاري کند.در قسمت بعدي در مورد نحوه نوشتن کوئري ها و همچنين استفاده از Fluent Api توضيحات بيشتري خواهم داد.
در قسمت دوم از سری آموزش Entity Framework در مورد کلاس DbContext و DbSet که دو کلاس اصلی در تعریف مدل بانک اطلاعاتی در سمت برنامه سی شارپ ما هستند صحبت می کنیم.
همانطوری که در بخش قبلی مطرح کردیم، کلاس Context ما باید از کلاس DbContext ارث بری کند. کلاس DbContext در حقیقت یک Container برای Entity های ما هست که وظیفه شناسایی و تعریف Mapping ها را به صورت خودکار انجام می دهد.
در حقیقت کلاس DbContext یک Wrapper بر روی ObjectContext که خیلی از ویژگی های این کلاس را به صورت خیلی ساده تر در اختیار ما قرار می دهد. البته خیلی از ویژگی های ObjectContext به صورت مستیقیم قابل دسترس نیست و باید به صورت غیر مستقیم به اونها دسترسی پیدا کرد.
کلاس هایی که از DbContext مشتق می شوند معمولا" دارای یک یا چند DbSet هستند. کلاس DbSet که یک کلاس Generic هست، اینترفیس IQueryable را پیاده سازی می کند تا بتوان از قابلیت LINQ در این کلاس برای نوشتن کوئری ها استفاده کرد.
هنگام ساختن یک شئ از کلاس مشتق شده از DbContext، تمامی DbSet ها شناسایی و پردازش می شوند تا Entity ها به جداول بانک اطلاعاتی Map شوند. عملیات Mapping به صورت خودکار انجام می شود که می توان از طریق متد OnModelCreating که یک متد Virtual هست، تغییرات دلخواه در مورد Mapping را اعمال کرد. مدل زیر را در نظر بگیرید:
public class Customer{ public int ID { get; set; } public string FirstName { get; set; } public string LastName { get; set; }}public class OrdersContext : DbContext{ public DbSet Customers { get; set; }}
براي مطالعه اين مقاله به ادامه مطلب رجوع کنيد. اگر مي خواهيد برنامه نويسي را بصورت حرفه ايي ياد بگيريد و اشنايي بيشتر با اين روابط به دوره آموزش سي شارپ در اين لينک مراجعه کنيد.
برچسب: آموزش زبان برنامه نویسی سی شارپ,دوره آموزشی سی شارپ,دوره سی شارپ,آموزش C,آموزش سی شارپ,
نویسنده: محمد نصیری