هر سه مورد فوق بهمراه یکدیگر معنا پیدا میکنند یعنی از Unitofwork و Repository در کنار کلاسهای poco یا همون code first یک مجموعه تشکیل داده و عملیات CRUD کار با بانک اطلاعاتی را انجام می دهیم
مسلما Code First اجماع نظر و محبوب اکثر برنامه نویسا هست بخاطر انعطاف پذیری و مدیریت بیشتر و راحتی تغییرات برنامه هست
ولی در dbfirst اگر از روی دیتابیس مهندسی معکوس بشه و تبدیل به code first هم عالیه
وقتی ما چند عملیات متعدد مثلا درج حذف یا ویرایش داریم که ممکنه همزمان نیاز داشته باشیم در دیتابیس این عملیاتها رو ثبت کنیم
مثلا یک فاکتور فروش در نظر بگیرید
1- سربرگ فاکتور
2- جزئیات و اقلام فاکتور
3- جزئیات پرداخت وجه فاکتور
4- پرسنل
اگر 3 مورد اول 3 تا موجودیت و یا سه تا جدول بهم متصل در بانک برنامه باشند و چنانچه بخواهیم یک فاکتور فروش ثبت کنیم و همزمان ثبت رکورد جدید در جدول اشخاص هم داشته باشیم مسلما نیاز داریم برای همه این عملیات ها یک وهله سازی جدید بر روی دیتاکانتکست برنامه داشته باشیم
var context= new ApplicationContext()
{
var person= new personnel{
id=1000,
name="ali",
.
.
.
}
context.personnel.AddOrUpdate(person)
//عملیات ویرایش پرسنل و ریختن در حافظه
Context.SaveChange()//ثبت در دیتابیس
}
var context= new ApplicationContext()
{
//عملیات ثبت سند فاکتور و ریختن در حافظه
Context.SaveChange() اعمال تغییرات در دیتابیس
}
اینجا 2 نمونه از دیتاکانتکست برنامه ساخته شده و بعد از عمل ذخیره سازی دو تراکنش بر روی بانک برنامه توسط متد savechange که از متدهای ذاتی entity framework هست انجام میشه
برای ایتکه تبدیل به یک تراکنش واحد بشه و مراجعات به بانک برنامه کمتر شده و جامعیت بانک نیز باید در نظر داشته باشیم
برای این کار از الگویی بنام Unit Of work بهره میبریم تا همه عملیات با یک دیتاکانتکس واحد و طی یک SaveChange درون دیتابیس ذخیره شود.
نه اینکه به ازای هر عمل یک دیتاکانتکست جدا ساخته و استفاده کنیم
معمولا از اینترفیسها interface برای الگوی واحد کار استفاده میشه
به عنوان مثال یک interface میسازیم
public interface IUnitOfWork
{
} int SaveAllChanges();
و اگر یک کلاس دیتاکانتکست بدین صورت داشته باشیم و از IunitOfWork ارث بری کنیم
public class ApplicationDbContext : DbContext,IUnitOfWork
{
}
و در نهایت وهله سازی دیتاکانتکست در قسمت جنرال برنامه یا یک جای عمومی بدینصورت داشته باشیم
IUnitOfWork uow= new ApplicationDbContext();
فقط کافیه
uow.SaveAllChanges();
رو درون متدهامون صدا بزنیم و به این میگن UnitOfWork
و اما Repository
اگر درون کدهای بالا نگاه کنید نوشته شده عملیات ویرایش پرسنل یا ثبت سند فاکتور
context.personnel.AddOrUpdate(person)
متد AddOrUpdate یکی از توابع ef برای درج و ویرایش رکورد هست
معمولا برنامه نویسها میان کلاسهای جدا به ازای هر کلاس ef میسازند و متدهایی درونش پیاده سازی میکنند و اسمش میزارن Repository
در برخی موارد نیازی هم نیست برای ساختن Repository
مثلل نوشتن برنامه ساده یا کوچک
البته هدف از Repository یکی کاهش کدنویسی و تکرار کدهای شبیه به هم هست و دیگری برای اعمال تزریق وابستگی و لایه بندی نرم افزار هست
public class PersonRepository
{
public void AddPerson(personnel p)
{
DbSet<personnel> i;
i.AddOrUpdate(p)
}
}
personnel همون کلاس code first هست
DbSet یک کلاس جنریک درون Ef هست و کوئری های ef که معادل کوئری sql هست توسط اون ساخته شده و روی بانک برنامه اعمال میشه
و در نهایت متد Addperson توی کلاسها یا جاههای دیگه صدا میزنند
البته این رو بصورت ساده و خلاصه گفتم
Repository خوب و کارامدتر با interface ها پیاده سازی میشن و مباحثی همچون تزریق وابستگی یا dependency injection هم به میون میاد که بحث طولانی تری داره ولی خیلی کاربرد مفید و جذابی داره