اگر پروژه تون از نوع data first بود و با ef کوئری روی جدولی زدین و این ارور رو گرفتین :
Data is Null. This method or property cannot be called on Null values.
علت این هست که
1. فیلدی در جدول دیتابیس دارین که allow null هست ولی در کلاس انتیتی سمت سی شارپ Required هست.
2. مقدار این ستون دیتابیس هست NULL هست.
من در data first برای ایجاد DbContext و کلاسهای poco یا همون Entity ها از اکستنشن ویژوال استودیو ef core power tools استفاده میکنم. برای نصب در Visual Studio منوی Extensions را باز کنید و Manage Extensions رو انتخاب کنید. از سمت چپ روی Online کلیک کنید و از سمت راست ef core power tools رو سرچ کنید و دکمه Download اش رو بزنید. بعد از نصب نیازه که یک بار vs رو ببندید و صبر کنید تا نصب بشه.
بعد از نصب کافیه روی پروژه وب (mvc core یا web api core یا Razor Pages) راست کلیک کنید و از منوی Ef Core Power Tools گزینه Reverse Engineer رو انتخاب کنید تا DbContext و مدل دوباره ساخته بشه و کد با دیتابیس sync بشه و این ارور بر طرف بشه.
بهتره در پروژه یک فولدر به نام Data بسازید برای ساختن فایل AppDbContext.cs در اون و داخل فولدر Data یه فولدر به نام Entities برای ساختن فایل های poco یا همون موجودیت که معادل جداول دیتابیس.
این اکستنشن موقع اینکار یعنی کار scaffold از دیتابیس به برنامه تنظیماتی هم داره که سیو هم میشه در پروژه تون و هر بار نمیخواد تنظیماتش رو انجام بدین. مثلا اسم کلاس DbContext رو میتونید بدین بهش ، محل ساخت فایلهای مدل poco و محل ساخت فایل DbContext رو میتونید بدین مثلا : Data یا Data/Entities ، همچنین اینکه اسم مدلها رو مفرد بسازه یا به صورت جمع.
البته این نکته رو مد نظر داشته باشین با توجه به این که هر بار عمل اسکفولد انجام میدین فایلها پاک میشن و دوباره ساخته میشه ، کدهایی که میتونید در AppDbContext نزارید رو نزارید که مجبور نشید هر بار اونارو بعد از ایجاد فایل جدید AppDbContext دوباره بنویسید. مثلا کانکشن استرینگ رو در فایل Program.cs که UseSqlServer میکنید پاس بدین.
اصلا هم سمت لایه Repository نرید چون خود کلاس DbContext ای اف کور که ما ازش ارث بری کردیم هر DbSet اش یک ریپازیتوری هست و برای 1 جدول هم Unit Of Work هست. تنها کافیه یک فولدر برای لایه Service بسازید (لایه ها رو با فولدر بسازید کارتون خیلی راحت میشه و ارور خیلی کمتری میگیرید) و داخلش interface ها و class های عملیاتی و بیزینسی سیستم تون رو بنویسید و به کانستراکتور کلاس ها مثلا ProductService تون AppDbContext رو inject کنید و عملیات دیتابیسی تون رو بنویسید. این interface ها و class ها رو در program.cs اینجکت کنید با AddScpoed و در کانستراکتور controller ها یا صفحات razor page اینجکت کنید و از متدهای سرویس ها استفاده کنید.
به دنبال ارث بری کلاسهای سرویس هم نباشید چون ارث بری یعنی اینکه یک سری متد مثل GetAll , GetById , Remove , Update رو به همه کلاسهای service بخورونید در حالیکه خیلی از انتیتی های یک سیستم مثلا Remove ندارن. هر متدی نیاز بود بنویسید که به لطف ef core عملیات دیتابیسی خیلی راحت شده.
برای توضیحات بیشتر عدم استفاده از لایه ریپازیتوری این لینک رو مطالعه کنید:
https://www.dntips.ir/post/841/ef-code-first-11
هدف uow این است که تعداد ساخت آبجکت از dbcontext رو در یک ریکوئست 1 دونه نگه داره تا عملیات کراد روی انتیتی های مختلف ترنزکشنال انجام بشه. آبجکت dbcontext خودش uow هم هست و اگر دو تا insert در 1 جدول یا 2 جدول مختلف انجام بدین اگر اینسرت اولی انجام بشه ولی دومی نشه کل عملیات rollback میشه پس اگه خواستین یه همچین کاری کنید که ترنزکشنال اجرا بشه هر دو عملیات رو در 1 متد سرویس و با 1 دی بی کانتکس انجام بدین و SaveChanges کنید.