اتریبیوت NotMapped در EF Core چه کاربردی دارد؟ چگونه از map شدن یک پراپرتی از کلاس در EF Core در روش CodeFirst و Fluent API جلوگیری کنیم ؟ چرا باید از مپ شدن یک Property از class با استفاده از NotMapped Attribute در روش کدفرست جلوگیری کنیم؟
سلام ، آرزو ابراهیمی هستم برنامه نویس ASP.NET و با یک مقاله آموزشی دیگر از فصل اموزش Entity Framework core از دوره اموزش asp در خدمت شما دوستان و همراهان همیشگی سایت میزفا هستم.
سرفصلهای پست
عدم Map شدن یک پراپرتی در روش Code First در EF Core
جهت جلوگیری از مپ شدن یک Property روش CodeFirst میتوانیم از دو روش استفاده کنیم که در ادامه این مقاله آموزشی با این دو روش آشنا خواهید شد.
[box type=”info” align=”” class=”” width=””]نکته : شاید این سوال برای شما همانند دانشجویان آموزش پروژه محور asp net core پیش بیاید که اصلا Map شدن به چه معناست ؟
خب من اصطلاح Map شدن را با یک مثال براتون توضیح میدم همونطور که خودتون بهتر از من میدونید در روش CodeFirst با تعریف یک کلاس و پراپرتی های آن کلاس ، یک جدول در دیتابیس میسازیم. در این دوره آموزش رایگان asp.net core هم یک کلاس تعریف کردیم به نام Student و برای آن پراپرتی هایی مثل StudentId و NationalCode و … را تعریف کردیم حالا زمانی که دیتابیس را آپدیت میکنیم پراپرتی StudentId باعث ایجاد یک ستون به نام StudentId در جدول میشود ، و ما اصطلاحا میگوییم که پراپرتی StudentId به ستون StudentId از جدول Map شده است.
[/box]عدم Map شدن یک پراپرتی به روش Data Annotation Attributes
در این روش جهت جلوگیری از Map شدن یک پراپرتی از کلاس از اتریبیوت[NotMapped]
بالای سر آن پراپرتی استفاده میکنیم.
حالا به سراغ پروژه جلسه آموزشی گذشته میرویم این پروژه را باز کنید اگر یادتان باشد در جلسه آموزشی گذشته با اتریبیوت Max-Length جهت محدود کردن طول داده ها در EF Core آشنا شدیم و حالا میخواهیم از اتریبیوت NoMapped برای یک پراپرتی جدید استفاده کنیم.
خب من یک پراپرتی جدید به نام Age از نوع int تعریف میکنم و چون نمیخواهم این پراپرتی به ستونی از جدول StudentMaster مپ شود بالای سر آن از اتریبیوت NoMapped استفاده میکنم ، مطابق با کد زیر :
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using System.Threading.Tasks; namespace EFCore_C05.Models { [Table("StudentMaster")] public class Student { [Key] public string StudentId { get; set; } [Required] public string NationalCode { get; set; } [Column("FirstName")] [MaxLength(50)] public string Name { get; set; } [Column("LastName"),MaxLength(50)] public string Family { get; set; } public DateTime BirthDate { get; set; } [NotMapped] public int Age { get; set; } } }
حالا فقط باید دیتابیس را آپدیت کنیم بعد از آپدیت دیتابیس ، خواهید دید که ستونی به نام Age در جدول StudentMaster نداریم چون با استفاده از اتریبوت NoMapped جلوی Map شدن این پراپرتی از کلاس را گرفتیم.
چنانچه با نحوه آپدیت دیتابیس در asp.net core آشنایی ندارید پیشنهاد میکنم مقاله آموزش update دیتابیس در EF Core را حتما مطالعه نمایید.
جلوگیری از Map شدن یک Property به روش Fluent API
با استفاده از روش Fluent API که در مقاله آموزشی پیکربندی کلاس های Domain در Code First با آن آشنا شدید هم میتوانید از Map شدن یک پراپرتی از کلاس ، جهت ایجاد ستونی جدید در جدول جلوگیری کنید.
ابتدا باید متد OnModelCreating را در کلاس Override ، StudentDBContext کنید سپس داخل این متد از کدهای زیر استفاده نمایید.
builder.Entity<Student>().Ignore(c => c.Age);
در کد بالا برای جلوگیری از Map شدن پراپرتی Age از متد Ignore()
استفاده کرده ایم. و سپس با استفاده از عبارات لامبدا پراپرتی Age را انتخاب کردیم به صورت c => c.Age .
پس متد OnModelCreating پس از تغییر به صورت زیر خواهد شد.
protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); builder.Entity<Student>().ToTable("StudentMaster").HasKey(b => b.StudentId); builder.Entity<Student>().Property(b => b.Name).HasColumnName("FirstName").HasMaxLength(50); builder.Entity<Student>().Property(b => b.Family).HasColumnName("LastName").HasMaxLength(50); builder.Entity<Student>().Property(b => b.NationalCode).IsRequired(); builder.Entity<Student>().Ignore(c => c.Age); }
کاربرد NotMapped Attribute در روش Code First
ممکن است این سوال برای شما پیش بیاد که اتربیوت NotMapped در EF Core چه کاربردی دارد؟ خب کاربرد این Attribute را با یک مثال برای شما توضیح میدهم ، فرض کنید که میخواهیم اطلاعات یک دانشجو را از Action Method به View ارسال کرده و سن دانشجوی مورد نظر را در View نمایش بدهیم ، ما می توانیم یک ViewModel دقیقا مشابه کلاس Student تعریف کرده سپس یک پراپرتی جدید به نام Age به آن اضافه کنیم و موقع ارسال اطلاعات سن دانشجو را با توجه به تاریخ تولدش محاسبه کرده و درون این پراپرتی ذخیره کنیم و یا میتوانیم از خود کلاس Student به جای کلاس ViewModel استفاده کنیم به این صورت که پراپرتی Age را به این کلاس اضافه کرده و بالای سر آن از اتریبیوت NotMapped استفاده کنیم و دیگر نیازی به تعریف یک کلاس ViewModel برای ارسال اطلاعات نیست.
از اینکه دوره آموزش net core. را دنبال میکنید، سپاسگزارم و امیدوارم براتون مفید بوده باشه. اگر سوال پیشنهاد و انتقادی داشتید خوشحال میشم که باهام در میان بگذارید و حتما در اولین فرصت بهتون پاسخ میدم.😊
4 پاسخ
سلام خانم ابراهیمی با تشکر ار اطلاعات بسیار بسیار مفیدتون لطفا اگه میشه یه مقدار بیشتر توضیخ بدین من دنبال automapper بودم که با این نکته آموزشی شما آشنا شدم یعنی میفرماین ما فقط از ویو مدل برای پاس دادن دیتا به ویو استفاده میکنیم و با لین روش دیگه نیازی نیست دیتا به ویو مدل مپ کنیم ؟
سلام من هر بار که از migration استفاده میکنم توی package manager console
این پیام:
Unable to create an object of type ‘DatabaseContext’. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728 error
رو نشون میده برای ساخت دیتابیس و آپدیت و …
چیکار باید بکنم
ممنون میشم راهنماییم کنین
سلام // با تشکر از سلسله مقاله های اموزش EF
جلوگیری از مپ شدن یک property در چه مواقعی کاربرد خواهد داشت ؟
سلام وقتتون بخیر
زمانیکه که بخواهیم داخل کلاس Entity یک پراپرتی تعریف کنیم ولی نمیخواهیم که به یک ستون از جدول Map شود ، به عنوان مثال می تونیم برای ارسال اطلاعات از اکشن متد به ویو از این کلاس Entity استفاده کنیم و هر تعداد پراپرتی که میخواهیم با اتریبیوت NotMapped درون این کلاس تعریف کنیم و دیگر نیازی به تعریف ViewModel نیست و مستقیما از کلاس Entity استفاده میکنیم.