مقاله کامل درباره Shadow Properties در Entity Framework

مقاله کامل در مورد Shadow Properties در EF Core

توسط admin | گروه برنامه نویسی | 1404/01/21

نظرات 0

مقاله کامل درباره Shadow Properties در Entity Framework

مقدمه

در Entity Framework (EF)، به طور پیش‌فرض هر ویژگی (Property) که در یک Entity تعریف می‌کنید، به عنوان یک ستون در دیتابیس ایجاد می‌شود. با این حال، در برخی موارد، ممکن است نیاز به ذخیره داده‌هایی در دیتابیس داشته باشید که هیچ ویژگی مشخصی در Entity خود نداشته باشند. برای این منظور، EF به شما اجازه می‌دهد که از Shadow Properties استفاده کنید. Shadow Properties ویژگی‌هایی هستند که در مدل‌های Entity تعریف نمی‌شوند، اما همچنان می‌توانند در دیتابیس ذخیره شوند.

در این مقاله، به توضیح مفاهیم Shadow Properties در Entity Framework پرداخته و یک مثال عملی با دو Entity به نام‌های Goods و GoodsGroup ارائه خواهیم داد.

Shadow Properties


بخش اول: مفهوم Shadow Properties

Shadow Properties ویژگی‌هایی هستند که به طور مستقیم در کد مدل Entity شما تعریف نمی‌شوند، اما در دیتابیس ذخیره می‌شوند. این ویژگی‌ها می‌توانند در مواردی استفاده شوند که بخواهید داده‌هایی را در دیتابیس ذخیره کنید که نیازی به دسترسی مستقیم به آن‌ها از طریق کد برنامه ندارید.

EF به طور خودکار برای این ویژگی‌ها در دیتابیس یک ستون ایجاد می‌کند، اما این ستون‌ها در مدل‌های C# شما قابل مشاهده نیستند. این ویژگی‌ها معمولاً برای ذخیره‌سازی داده‌هایی که برای نظارت، زمان‌بندی، یا دیگر کاربردهای موقت استفاده می‌شوند، مفید هستند.

ویژگی‌های Shadow Properties

  1. عدم نیاز به تعریف در کد: Shadow Properties نیازی به تعریف در کلاس Entity ندارند.

  2. ذخیره‌سازی در دیتابیس: این ویژگی‌ها می‌توانند به عنوان ستون‌هایی در دیتابیس ذخیره شوند.

  3. دسترسی از طریق API EF: شما می‌توانید به این ویژگی‌ها از طریق API Entity Framework دسترسی پیدا کنید.


بخش دوم: استفاده از Shadow Properties

در EF، برای ایجاد یک Shadow Property شما باید آن را در OnModelCreating و از طریق Fluent API تعریف کنید.

مثال عملی: تعریف Shadow Properties در Entity Framework

فرض کنید دو Entity داریم:

  • Goods: این Entity شامل اطلاعات مربوط به کالاها است.

  • GoodsGroup: این Entity برای گروه‌بندی کالاها استفاده می‌شود.

در این مثال، فرض کنید می‌خواهیم اطلاعاتی مانند تاریخ ایجاد (CreationDate) و تاریخ به‌روزرسانی (LastModifiedDate) را برای هر دو Entity ذخیره کنیم. این اطلاعات ممکن است برای نظارت و مدیریت رکوردها مفید باشند، اما نیازی به تعریف مستقیم این ویژگی‌ها در مدل‌ها نداریم.

مرحله 1: تعریف کلاس‌ها

ابتدا دو Entity Goods و GoodsGroup را تعریف می‌کنیم:

 
 
public class Goods {
public int Id { get; set; }
public string Name { get; set; }
public int GroupId { get; set; }
public GoodsGroup GoodsGroup { get; set; }
}
public class GoodsGroup
{
public int Id { get; set; }
public string GroupName { get; set; }
}

در اینجا، Goods دارای یک ارتباط به GoodsGroup است که نشان‌دهنده گروه کالا است.

مرحله 2: استفاده از Shadow Properties

در مرحله بعد، ما ویژگی‌های CreationDate و LastModifiedDate را به صورت Shadow Property تعریف می‌کنیم. این ویژگی‌ها در مدل‌های Entity ما وجود ندارند، اما می‌خواهیم آن‌ها را در دیتابیس ذخیره کنیم.

 
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// تعریف Shadow Property برای تاریخ ایجاد
modelBuilder.Entity<Goods>()
.Property<DateTime>("CreationDate");
// تعریف Shadow Property برای تاریخ آخرین به روزرسانی
modelBuilder.Entity<Goods>()
.Property<DateTime>("LastModifiedDate");
// همچنین می‌توانیم برای GoodsGroup هم ویژگی‌های مشابهی تعریف کنیم
modelBuilder.Entity<GoodsGroup>()
.Property<DateTime>("CreationDate");
}

در این مثال، CreationDate و LastModifiedDate به عنوان Shadow Properties برای Entity های Goods و GoodsGroup تعریف شده‌اند.

مرحله 3: دسترسی به Shadow Properties

برای دسترسی به Shadow Properties باید از API مربوط به EF استفاده کنیم. برای مثال، برای دسترسی به CreationDate در Entity Goods، می‌توانیم به شکل زیر عمل کنیم:

 
var goods = context.Goods.FirstOrDefault(g => g.Id == 1);
var creationDate = context.Entry(goods).Property("CreationDate").CurrentValue;
Console.WriteLine($"Creation Date: {creationDate}");

در اینجا از متد Entry برای دسترسی به اطلاعات Entity و سپس از Property برای دریافت مقدار Shadow Property استفاده کرده‌ایم.


بخش سوم: کاربردهای Shadow Properties

  1. تاریخ‌ها و اطلاعات متا: معمولاً از Shadow Properties برای ذخیره تاریخ‌های ایجاد و به‌روزرسانی، وضعیت رکوردها (مثل "حذف شده" یا "فعال")، یا اطلاعات متا استفاده می‌شود.

  2. ایجاد رکوردهای سیستمی: اگر نیاز به ذخیره داده‌هایی دارید که به صورت خودکار در سطح سیستم مدیریت می‌شوند (مثل اطلاعات تاریخی)، می‌توانید از این ویژگی‌ها بهره‌برداری کنید.

  3. فراهم کردن انعطاف‌پذیری: برای پروژه‌هایی که ویژگی‌های خاصی باید به صورت پویا اضافه شوند، Shadow Properties به شما انعطاف‌پذیری می‌دهند بدون اینکه نیاز به تغییرات زیاد در مدل‌های Entity داشته باشید.


جمع‌بندی

Shadow Properties در Entity Framework ابزار بسیار مفیدی هستند که به شما این امکان را می‌دهند که داده‌های اضافی را در دیتابیس ذخیره کنید بدون اینکه بخواهید آن‌ها را به صورت صریح در مدل‌های Entity خود تعریف کنید. این ویژگی به خصوص در مواردی که نیاز به ذخیره‌سازی اطلاعات متا یا تاریخ‌های خودکار دارید، بسیار کاربردی است. با استفاده از این تکنیک، می‌توانید کارایی و انعطاف‌پذیری بیشتری در پروژه‌های خود داشته باشید.

ایجاد و استفاده از Shadow Properties

در این بخش، نحوه تعریف و استفاده از Shadow Property را در Entity Framework بررسی خواهیم کرد. برای مثال، فرض کنید دو Entity به نام‌های Goods و GoodsGroup داریم. در این مثال، ما می‌خواهیم ویژگی‌هایی مانند GroupId را به صورت Shadow Property ایجاد کنیم، که در ارتباط بین این دو Entity به صورت خودکار توسط EF مدیریت خواهد شد.

مرحله 1: تعریف کلاس‌های Goods و GoodsGroup

ابتدا دو کلاس Entity به نام‌های Goods و GoodsGroup را تعریف می‌کنیم. در اینجا، فرض می‌کنیم که GroupId در کلاس Goods به طور مستقیم تعریف نشده است، اما EF به طور خودکار آن را ایجاد خواهد کرد.

 
public class Goods {
public int Id { get; set; }
public string Name { get; set; }
public GoodsGroup GoodsGroup { get; set; }
}
public class GoodsGroup {
public int Id { get; set; }
public string GroupName { get; set; }
}

در اینجا، ما هیچ ویژگی GroupId در کلاس Goods نداریم، اما انتظار داریم که EF این ویژگی را به طور خودکار برای ایجاد ارتباط بین Goods و GoodsGroup ایجاد کند.

مرحله 2: استفاده از Fluent API برای ایجاد ارتباط و Shadow Property

در مرحله بعد، برای ایجاد ارتباط بین Goods و GoodsGroup و همچنین ایجاد Shadow Property برای GroupId از Fluent API استفاده می‌کنیم.

 
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// ایجاد ارتباط بین Goods و GoodsGroup
modelBuilder.Entity<Goods>()
.HasOne(g => g.GoodsGroup)
.WithMany()
.HasForeignKey("GroupId");
// اینجا GroupId به عنوان Shadow Property ایجاد می‌شود
// تعریف Shadow Property برای GroupId
modelBuilder.Entity<Goods>()
.Property<int>("GroupId");
}

در اینجا، ما از Fluent API برای ایجاد ارتباط یک به بسیاری (One-to-Many) بین Goods و GoodsGroup استفاده کرده‌ایم. همچنین، GroupId به صورت Shadow Property تعریف شده است.

Shadow Properties in EF Core

مرحله 3: دسترسی به Shadow Property

حالا که GroupId به عنوان Shadow Property ایجاد شده است، می‌توانیم به این ویژگی از طریق EF دسترسی پیدا کنیم. برای دسترسی به Shadow Property، باید از متد Entry و Property استفاده کنیم:

 
var goods = context.Goods.FirstOrDefault(g => g.Id == 1);
// دسترسی به Shadow Property "GroupId"
var groupId = context.Entry(goods).Property("GroupId").CurrentValue;
Console.WriteLine($"GroupId: {groupId}");

در اینجا، با استفاده از Entry و Property می‌توانیم به Shadow Property GroupId دسترسی پیدا کنیم.


بخش سوم: نحوه اعمال داده به Shadow Property

در این بخش، نحوه اعمال داده به Shadow Property به ویژه برای GroupId که در ارتباط بین Goods و GoodsGroup استفاده می‌شود، بررسی می‌کنیم.

فرض کنید می‌خواهید یک شیء از Goods ایجاد کنید و به طور مستقیم داده‌ای را به GroupId که در حالت Shadow ایجاد شده است، اعمال کنید.

برای اعمال داده به Shadow Property، می‌توانیم از متد Property استفاده کنیم و مقدار مورد نظر را به آن اختصاص دهیم:

 
var goods = new Goods
{
Name = "Example Good"
};
// اعمال داده به Shadow Property "GroupId"
context.Entry(goods).Property("GroupId").CurrentValue = 1;
context.Goods.Add(goods); context.SaveChanges();
 

در اینجا، مقدار GroupId به طور مستقیم به Shadow Property اختصاص داده شده است و سپس شیء Goods به دیتابیس ذخیره می‌شود.


بخش چهارم: مزایای استفاده از Shadow Properties

استفاده از Shadow Properties در Entity Framework می‌تواند مزایای زیادی داشته باشد، از جمله:

  1. افزایش انعطاف‌پذیری: شما می‌توانید ویژگی‌هایی را بدون نیاز به تغییر مدل‌های Entity خود ذخیره کنید.

  2. مدیریت بهینه ارتباطات: EF به طور خودکار ارتباطات را مدیریت کرده و Shadow Property‌ها را ایجاد می‌کند، بدون اینکه نیازی به اضافه کردن ویژگی‌های اضافی در کلاس‌ها باشد.

  3. پشتیبانی از ویژگی‌های سیستم: شما می‌توانید ویژگی‌های سیستم مانند تاریخ‌های ایجاد و به‌روزرسانی را به صورت Shadow Property اضافه کنید.

 

Shadow Properties در Entity Framework یک ویژگی مفید است که به شما این امکان را می‌دهد که داده‌ها را در دیتابیس ذخیره کنید بدون اینکه آن‌ها را به طور مستقیم در مدل‌های Entity خود تعریف کنید. این ویژگی به خصوص در مواردی که نیاز به ذخیره‌سازی اطلاعات متا یا تاریخ‌های خودکار دارید، بسیار کاربردی است. با استفاده از Fluent API می‌توان ارتباطات را ایجاد کرده و Shadow Property‌ها را به راحتی مدیریت کرد. این قابلیت به شما این امکان را می‌دهد که انعطاف‌پذیری بیشتری در طراحی مدل‌های دیتابیس خود داشته باشید و از EF به شکل بهینه‌تری استفاده کنید.

Shadow Properties in EF Core

 

مراحل استفاده از Migration برای Shadow Property

1. تعریف Shadow Property در مدل‌ها

همانطور که در بخش‌های قبلی توضیح دادیم، ابتدا باید Shadow Property را در مدل‌ها تعریف کنید. فرض کنید که ما دو Entity به نام‌های Goods و GoodsGroup داریم و از GroupId به عنوان Shadow Property برای ارتباط بین این دو استفاده می‌کنیم.

 
public class Goods
{
public int Id { get; set; }
public string Name { get; set; }
public GoodsGroup GoodsGroup { get; set; }
}
public class GoodsGroup
{
public int Id { get; set; }
public string GroupName { get; set; }
}

سپس، در متد OnModelCreating از Fluent API استفاده می‌کنیم تا ارتباط بین Goods و GoodsGroup و همچنین Shadow Property برای GroupId را تعریف کنیم:

 
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// ایجاد ارتباط بین Goods و GoodsGroup
modelBuilder.Entity<Goods>()
.HasOne(g => g.GoodsGroup)
.WithMany()
.HasForeignKey("GroupId");
// اینجا GroupId به عنوان Shadow Property ایجاد می‌شود
// تعریف Shadow Property برای GroupId
modelBuilder.Entity<Goods>()
.Property<int>("GroupId");
}

2. اجرای دستور Migration

پس از اینکه تغییرات مورد نظر را در مدل‌ها ایجاد کردید، مرحله بعدی ایجاد Migration برای اعمال این تغییرات به دیتابیس است.

در ترمینال یا کنسول Package Manager دستور زیر را برای ایجاد Migration وارد کنید:

 
dotnet ef migrations add AddGroupIdShadowProperty

یا در کنسول Package Manager دستور زیر را وارد کنید:

 
Add-Migration AddGroupIdShadowProperty

این دستور باعث می‌شود که EF یک Migration جدید به نام AddGroupIdShadowProperty ایجاد کند. در این مرحله، EF به صورت خودکار فیلد GroupId را به عنوان Shadow Property شبیه به سایر ویژگی‌ها شبیه‌سازی خواهد کرد و آن را در فایل Migration به شکل زیر نمایش می‌دهد.

3. مشاهده محتوای Migration

در پوشه Migrations، یک فایل به نام AddGroupIdShadowProperty ایجاد خواهد شد که به طور مشابه به سایر Migrations، شامل کدهایی است که تغییرات دیتابیس را نشان می‌دهند.

این فایل ممکن است چیزی شبیه به این باشد:

 
public partial class AddGroupIdShadowProperty : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
// ایجاد ستون GroupId به عنوان Shadow Property
migrationBuilder.AddColumn<int>(
name: "GroupId",
table: "Goods",
nullable: true);
// یا nullable: false بستگی به تنظیمات شما دارد
// تنظیم کلید خارجی برای ارتباط
migrationBuilder.CreateIndex(
name: "IX_Goods_GroupId",
table: "Goods",
column: "GroupId");
migrationBuilder.AddForeignKey(
name: "FK_Goods_GoodsGroups_GroupId",
table: "Goods",
column: "GroupId",
principalTable: "GoodsGroups",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
// تنظیم رفتار هنگام حذف
}
protected override void Down(MigrationBuilder migrationBuilder)
{
// حذف ستون GroupId
migrationBuilder.DropForeignKey(
name: "FK_Goods_GoodsGroups_GroupId",
table: "Goods");
migrationBuilder.DropIndex(
name: "IX_Goods_GroupId",
table: "Goods");
migrationBuilder.DropColumn(
name: "GroupId",
table: "Goods");
}
}

در اینجا، EF به طور خودکار ستون GroupId را در جدول Goods ایجاد می‌کند و این ستون را به عنوان یک کلید خارجی به جدول GoodsGroups متصل می‌کند.

4. اعمال Migration به دیتابیس

پس از ایجاد Migration، می‌توانید آن را به دیتابیس اعمال کنید تا تغییرات در دیتابیس ذخیره شوند. برای این کار، دستور زیر را وارد کنید:

 
dotnet ef database update

 

یا در کنسول Package Manager دستور زیر را وارد کنید:

 
 
Update-Database

این دستور باعث می‌شود که Migration جدید اجرا شده و ستون GroupId به دیتابیس اضافه شود.

5. مشاهده تغییرات در دیتابیس

پس از اجرای Migration و به‌روزرسانی دیتابیس، اگر به دیتابیس نگاه کنید، خواهید دید که یک ستون جدید به نام GroupId به جدول Goods اضافه شده است. این ستون به عنوان یک Shadow Property در نظر گرفته شده و از طریق Fluent API برای ایجاد ارتباط با GoodsGroup استفاده می‌شود. در این مقاله، نحوه استفاده از Shadow Properties در Entity Framework و چگونگی ایجاد Migration برای افزودن این ویژگی‌ها به دیتابیس را بررسی کردیم. استفاده از Shadow Properties به شما این امکان را می‌دهد که بدون نیاز به تعریف ویژگی‌های اضافی در مدل‌های خود، داده‌هایی را در دیتابیس ذخیره کنید. با استفاده از Fluent API می‌توانید ارتباطات و ویژگی‌های اضافی را به مدل‌های خود اضافه کنید، و سپس با استفاده از Migration تغییرات را به دیتابیس اعمال کنید.

تاثیر Shadow Properties بر UI 

در EF Core، Shadow Properties خود به خود باعث کاهش سرعت UI نمی‌شوند، زیرا این ویژگی‌ها تنها در سطح پایگاه داده و مدل‌های EF Core وجود دارند و در کد C# و UI هیچ‌گونه تأثیر مستقیمی ندارند.

توضیح بیشتر:

  • عملکرد UI تحت تأثیر فرآیندهای دریافت داده‌ها و رندرینگ در UI است. اگر داده‌ها به سرعت از پایگاه داده بارگذاری شوند، UI سریع‌تر و روان‌تر خواهد بود. از آنجا که Shadow Properties در پایگاه داده ذخیره می‌شوند و به طور مستقیم در کد یا UI تاثیر ندارند، در صورتی که در کوئری‌ها استفاده شوند، هیچ تأثیری بر رندر UI ندارند.

  • فرآیندهای کوئری و داده‌ها: تأثیر واقعی Shadow Properties بر سرعت پایگاه داده است، نه سرعت UI. اگر این ویژگی‌ها در کوئری‌ها استفاده شوند و پایگاه داده را تحت فشار قرار دهند (مثل ایجاد کوئری‌های پیچیده یا استفاده از فیلترهای سنگین)، ممکن است سرعت واکنش‌های پایگاه داده کاهش یابد، که در نهایت زمان بارگذاری داده‌ها برای UI را تحت تأثیر قرار می‌دهد.

Shadow Properties به خودی خود تأثیری بر سرعت UI ندارند، اما اگر در کوئری‌ها به صورت نادرست یا به‌طور پیچیده استفاده شوند، می‌توانند زمان بارگذاری داده‌ها را افزایش دهند و این امر می‌تواند به طور غیرمستقیم باعث کاهش سرعت UI شود، به‌ویژه اگر داده‌های زیادی از پایگاه داده بارگذاری شوند. پس، در صورت استفاده بهینه از Shadow Properties و کوئری‌های بهینه، تأثیری بر UI نخواهید داشت.

 

0 نظر

نظر محترم شما در مورد مقاله های وب سایت برنامه نویسی و پایگاه داده

نظرات محترم شما در خدمات رسانی بهتر ما را یاری می نمایند. لطفا اگر مایل بودید یک نظر ما را مهمان فرمائید. آدرس ایمیل و وب سایت شما نمایش داده نخواهد شد.

حرف 500 حداکثر

اطلاعات تماس

  • آدرس:اصفهان-خیابان ام کلثوم غربی - بعد خیابان تخم چی - بیست متر بعد از پیتزا ننه شب - کوچه تعمیر گاه سمار زغالی - پلاک 354 - درب مشکی - طبقه هفتم
  • آدرس ایمیل:najafzade@gmail.com
  • وب سایت:http://www.a00b.com/
  • تلفن ثابت:(+98)9131253620
  • تلفن همراه:09131253620