آموزش Entity Framework فارسی

تاریخ: 1404/12/4 ساعت: 11:14 بازدید: 15

Entity Framework چیست و چرا باید یاد بگیریم؟

اگر با دات‌نت کار می‌کنی، احتمالاً اسم Entity Framework به گوشت خورده. ولی شاید هنوز دقیقاً ندونی این ابزار چیه و چرا دنیای برنامه‌نویسی C# بدون اون ناقصه. خب، بذار خیلی ساده توضیح بدم.

Entity Framework (EF) یک ORM یا Object-Relational Mapper هست که مایکروسافت اون رو ساخته. کار اصلیش اینه که بین دنیای شیءگرای C# و دنیای رابطه‌ای دیتابیس (مثل SQL Server) یه پل ارتباطی ایجاد کنه.

به زبون ساده‌تر: به جای اینکه تو کدت مستقیم SQL بنویسی، با Entity Framework می‌تونی با همون کلاس‌های C# خودت با دیتابیس حرف بزنی. این یعنی کد تمیزتر، توسعه سریع‌تر و خطاهای کمتر!

مزایای Entity Framework نسبت به ADO.NET

  • سرعت توسعه بالاتر: دیگه لازم نیست برای هر عملیات CRUD دستی SQL بنویسی.
  • کاهش خطای انسانی: EF کوئری‌ها رو خودش مدیریت می‌کنه.
  • پشتیبانی از چند دیتابیس: با تغییر Provider می‌تونی از SQL Server به PostgreSQL یا MySQL بری.
  • Migrations قدرتمند: تغییرات دیتابیس رو به راحتی مدیریت کن.
  • LINQ Integration: با LINQ کوئری بزن، طبیعی‌ترین روش ممکن!

تفاوت Entity Framework و Entity Framework Core

خیلی از کاربران ایرانی می‌پرسن: «EF Classic با EF Core چه فرقی دارن؟» این سوال مهمیه. بذار واضح توضیح بدم:

  • Entity Framework 6 (EF6): نسخه کلاسیک، فقط برای پروژه‌های .NET Framework، دیگه آپدیت جدی نمی‌گیره.
  • Entity Framework Core (EF Core): نسخه جدید، کراس‌پلتفرم، مناسب .NET 5/6/7/8، فعالانه توسعه داده می‌شه.

توصیه ما؟ اگه پروژه جدید شروع می‌کنی، حتماً EF Core استفاده کن. این آموزش هم بیشتر روی EF Core تمرکز داره.

نصب Entity Framework Core در پروژه

برای شروع، باید EF Core رو به پروژه‌ات اضافه کنی. این کار از طریق NuGet Package Manager یا CLI انجام می‌شه.

نصب از طریق Package Manager Console

در Visual Studio، پنجره Package Manager Console رو باز کن و دستورات زیر رو اجرا کن:


Install-Package Microsoft.EntityFrameworkCore

Install-Package Microsoft.EntityFrameworkCore.SqlServer

Install-Package Microsoft.EntityFrameworkCore.Tools

نصب از طریق dotnet CLI


dotnet add package Microsoft.EntityFrameworkCore

dotnet add package Microsoft.EntityFrameworkCore.SqlServer

dotnet add package Microsoft.EntityFrameworkCore.Tools

سه رویکرد اصلی در Entity Framework

EF Core سه رویکرد مختلف داره که باید بشناسیشون:

۱. Code First (کد اول)

پرکاربردترین روش! تو اول کلاس‌های C# خودت رو می‌نویسی، بعد EF از روی اون‌ها جدول‌های دیتابیس می‌سازه. این روش کنترل بیشتری به توسعه‌دهنده می‌ده.

۲. Database First (دیتابیس اول)

وقتی دیتابیس از قبل وجود داره، EF از روی اون کلاس‌های C# می‌سازه. برای پروژه‌های Legacy مناسبه.

۳. Model First (مدل اول)

از طریق طراح گرافیکی، مدل داده‌ها رو می‌کشی و EF هم کلاس و هم دیتابیس رو می‌سازه. امروزه کمتر استفاده می‌شه.

آموزش Code First از صفر

بذار با یه مثال عملی پیش بریم. فرض کن داریم یه سیستم مدیریت کتاب‌خونه می‌سازیم.

مرحله ۱: ساخت Entity Class


public class Book

{

public int Id { get; set; }

public string Title { get; set; }

public string Author { get; set; }

public DateTime PublishedDate { get; set; }

public decimal Price { get; set; }

// Navigation Property

public int CategoryId { get; set; }

public Category Category { get; set; }

}

public class Category

{

public int Id { get; set; }

public string Name { get; set; }

// Navigation Property

public List Books { get; set; }

}

مرحله ۲: ساخت DbContext

DbContext قلب Entity Framework هست. این کلاس ارتباط بین کد C# تو و دیتابیس رو مدیریت می‌کنه.


public class LibraryContext : DbContext

{

public LibraryContext(DbContextOptions options)

: base(options)

{

}

public DbSet Books { get; set; }

public DbSet Categories { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)

{

modelBuilder.Entity()

.Property(b => b.Price)

.HasColumnType(“decimal(18,2)”);

modelBuilder.Entity()

.HasOne(b => b.Category)

.WithMany(c => c.Books)

.HasForeignKey(b => b.CategoryId);

}

}

مرحله ۳: تنظیم Connection String

در فایل appsettings.json رشته اتصال به دیتابیس رو تنظیم کن:


{

“ConnectionStrings”: {

“DefaultConnection”: “Server=.;Database=LibraryDB;Trusted_Connection=True;TrustServerCertificate=True;”

}

}

مرحله ۴: ثبت DbContext در Program.cs


builder.Services.AddDbContext(options =>

options.UseSqlServer(

builder.Configuration.GetConnectionString(“DefaultConnection”)

)

);

Migrations در Entity Framework Core

Migration یکی از قدرتمندترین ویژگی‌های EF Core هست. با این ابزار، هر تغییری که تو کلاس‌هات بدی، به‌صورت کنترل‌شده روی دیتابیس اعمال می‌شه.

دستورات اصلی Migration


ساخت اولین Migration

Add-Migration InitialCreate

اعمال Migration روی دیتابیس

Update-Database

برگشت به Migration قبلی

Update-Database PreviousMigrationName

حذف آخرین Migration (اگه هنوز اعمال نشده)

Remove-Migration

عملیات CRUD با Entity Framework

حالا بریم سراغ عملی‌ترین بخش: ایجاد، خواندن، به‌روزرسانی و حذف داده.

افزودن داده (Create)


using (var context = new LibraryContext(options))

{

var book = new Book

{

Title = “برنامه‌نویسی با C#”,

Author = “علی محمدی”,

PublishedDate = DateTime.Now,

Price = 150000,

CategoryId = 1

};

context.Books.Add(book);

await context.SaveChangesAsync();

}

خواندن داده (Read) با LINQ


// خواندن همه کتاب‌ها

var allBooks = await context.Books

.Include(b => b.Category)

.ToListAsync();

// فیلتر کردن

var cheapBooks = await context.Books

.Where(b => b.Price < 200000)

.OrderBy(b => b.Title)

.ToListAsync();

// یک آیتم خاص

var book = await context.Books

.FirstOrDefaultAsync(b => b.Id == 1);

به‌روزرسانی داده (Update)


var book = await context.Books.FindAsync(1);

if (book != null)

{

book.Price = 180000;

book.Title = “عنوان جدید”;

await context.SaveChangesAsync();

}

حذف داده (Delete)


var book = await context.Books.FindAsync(1);

if (book != null)

{

context.Books.Remove(book);

await context.SaveChangesAsync();

}

روابط در Entity Framework Core

یکی از مهم‌ترین مفاهیمی که باید بلد باشی، روابط بین Entity ها هست.

رابطه One-to-Many (یک به چند)

مثل رابطه Category و Book که بالا دیدیم. یک دسته‌بندی می‌تونه چند کتاب داشته باشه.

رابطه Many-to-Many (چند به چند)


public class Student

{

public int Id { get; set; }

public string Name { get; set; }

public List Courses { get; set; } = new();

}

public class Course

{

public int Id { get; set; }

public string Title { get; set; }

public List Students { get; set; } = new();

}

EF Core 5+ این رابطه رو بدون نیاز به جدول واسط مستقیم مدیریت می‌کنه!

رابطه One-to-One (یک به یک)


public class User

{

public int Id { get; set; }

public string Username { get; set; }

public UserProfile Profile { get; set; }

}

public class UserProfile

{

public int Id { get; set; }

public string Bio { get; set; }

public int UserId { get; set; }

public User User { get; set; }

}

Eager Loading، Lazy Loading و Explicit Loading

این سه مفهوم یکی از سوالات رایج در مصاحبه‌های برنامه‌نویسی ایرانیه!

  • Eager Loading: با Include()، داده‌های مرتبط رو همزمان بارگذاری کن. بهترین انتخاب در اکثر موارد.
  • Lazy Loading: داده‌های مرتبط فقط وقتی که بهشون دسترسی پیدا می‌کنی بارگذاری می‌شن. نیاز به نصب پکیج مخصوص داره.
  • Explicit Loading: دستی تعیین می‌کنی کِی داده‌های مرتبط بارگذاری بشن. بیشترین کنترل رو بهت می‌ده.

⚠️ مشکل N+1 Query

یکی از بزرگ‌ترین اشتباهات در کار با EF، مشکل N+1 Query هست. وقتی از Lazy Loading بدون دقت استفاده کنی، برای هر آیتم یه کوئری جداگانه به دیتابیس می‌زنه. همیشه کوئری‌هات رو با SQL Profiler بررسی کن!

بهینه‌سازی کوئری‌ها در EF Core

EF Core ابزارهای عالی برای بهینه‌سازی داره:

  • AsNoTracking(): برای کوئری‌های فقط-خواندنی. سرعت رو به شکل چشمگیری بالا می‌بره.
  • Select() Projection: فقط فیلدهای مورد نیاز رو واکشی کن، نه همه ستون‌ها.
  • Compiled Queries: کوئری‌های پرتکرار رو کامپایل کن تا سریع‌تر اجرا بشن.
  • Pagination: از Skip() و Take() برای صفحه‌بندی استفاده کن.

// بهینه: AsNoTracking + Select

var books = await context.Books

.AsNoTracking()

.Where(b => b.CategoryId == 1)

.Select(b => new { b.Id, b.Title, b.Price })

.Skip(0)

.Take(10)

.ToListAsync();

🚀 سایت شما هم می‌تونه صفحه اول گوگل باشه!

آیا می‌خواهید سایت شما هم مثل رقبا در صفحه اول گوگل باشد و زنگ‌خورهایتان چند برابر شود؟ سئوی سایت خود را به متخصصان ما بسپارید. همین حالا برای مشاوره رایگان با ما تماس بگیرید:

📞 09190994063  |  09376846692

Data Annotations در EF Core

با Data Annotations می‌تونی مستقیم روی کلاس‌هات، قوانین دیتابیس رو تعریف کنی:


using System.ComponentModel.DataAnnotations;

using System.ComponentModel.DataAnnotations.Schema;

public class Book

{

[Key]

public int Id { get; set; }

[Required]

[MaxLength(200)]

[Column(“BookTitle”)]

public string Title { get; set; }

[Required]

[MaxLength(100)]

public string Author { get; set; }

[Column(TypeName = “decimal(18,2)”)]

[Range(0, 10000000)]

public decimal Price { get; set; }

[NotMapped]

public string DisplayName => $“{Title} - {Author}”;

}

Fluent API در مقابل Data Annotations

دو روش برای تنظیمات مدل وجود داره: Data Annotations (ساده‌تر ولی محدودتر) و Fluent API (پیچیده‌تر ولی قدرتمندتر).

توصیه حرفه‌ای: برای پروژه‌های بزرگ، از Fluent API در یک فایل جداگانه استفاده کن تا کلاس‌های Entity تمیز بمونن.


public class BookConfiguration : IEntityTypeConfiguration

{

public void Configure(EntityTypeBuilder builder)

{

builder.HasKey(b => b.Id);

builder.Property(b => b.Title)

.IsRequired()

.HasMaxLength(200);

builder.Property(b => b.Price)

.HasColumnType(“decimal(18,2)”);

builder.HasIndex(b => b.Author);

}

}

الگوی Repository Pattern با EF Core

در پروژه‌های واقعی، مستقیم از DbContext در Controller استفاده نمی‌کنیم. به جاش از Repository Pattern استفاده می‌کنیم تا کد تمیز‌تر و قابل‌تست‌تر بشه.


public interface IBookRepository

{

Task> GetAllAsync();

Task GetByIdAsync(int id);

Task AddAsync(Book book);

Task UpdateAsync(Book book);

Task DeleteAsync(int id);

}

public class BookRepository : IBookRepository

{

private readonly LibraryContext _context;

public BookRepository(LibraryContext context)

{

_context = context;

}

public async Task> GetAllAsync()

{

return await _context.Books

.AsNoTracking()

.Include(b => b.Category)

.ToListAsync();

}

// … سایر متدها

}

اجرای Raw SQL در EF Core

بعضی وقت‌ها نیاز داری مستقیم SQL اجرا کنی. EF Core این امکان رو هم داره:


// کوئری SQL با Parameterized Query (امن در برابر SQL Injection)

var books = await context.Books

.FromSqlRaw(“SELECT * FROM Books WHERE Price > {0}”, 100000)

.ToListAsync();

// اجرای دستورات SQL

await context.Database.ExecuteSqlRawAsync(

“UPDATE Books SET Price = Price * 1.1 WHERE CategoryId = {0}”, 1

);

💡 یه نکته مهم از تیم ما:

همون‌طور که یادگیری Entity Framework به پروژه‌های نرم‌افزاریت رونق می‌ده، سئوی حرفه‌ای هم به کسب‌وکار آنلاینت رونق می‌ده. سایتی که در گوگل دیده نشه، مثل مغازه‌ایه که تابلو نداره!

آیا می‌خواهید سایت شما هم مثل رقبا در صفحه اول گوگل باشد و زنگ‌خورهایتان چند برابر شود؟ سئوی سایت خود را به متخصصان ما بسپارید. همین حالا برای مشاوره رایگان با ما تماس بگیرید: 09190994063 - 09376846692

نکات پیشرفته EF Core که باید بدونی

  • Global Query Filters: برای Soft Delete و Multi-Tenancy عالیه.
  • Owned Entity Types: برای Value Object در DDD.
  • Table Splitting: یک جدول رو به چند Entity تقسیم کن.
  • Temporal Tables: تاریخچه تغییرات داده رو نگه‌دار (EF Core 6+).
  • Bulk Operations: برای عملیات روی حجم زیاد داده از کتابخانه‌های مثل EFCore.BulkExtensions استفاده کن.

خطاهای رایج در EF Core و راه‌حل آن‌ها

  • ObjectDisposedException: معمولاً وقتی Context رو خارج از Scope استفاده می‌کنی رخ می‌ده. از Dependency Injection درست استفاده کن.
  • Circular Reference در Serialization: از DTO یا JsonIgnore استفاده کن.
  • Migration Conflicts: وقتی چند توسعه‌دهنده همزمان Migration اضافه می‌کنن. با Merge اون‌ها رو حل کن.
  • Slow Queries: با AsNoTracking و Projection بهینه‌سازی کن.

سوالات متداول (FAQ)

آیا Entity Framework برای پروژه‌های بزرگ مناسبه؟

بله، Entity Framework Core در پروژه‌های Enterprise بزرگ هم استفاده می‌شه. با رعایت نکات بهینه‌سازی مثل AsNoTracking، Pagination، ایندکس‌گذاری مناسب و استفاده از Compiled Queries، می‌تونی به عملکرد بسیار خوبی برسی. شرکت‌های بزرگ دنیا از EF Core در محصولاتشون استفاده می‌کنن.

تفاوت EF Core با Dapper چیه و کدوم رو انتخاب کنم؟

Dapper یک Micro-ORM هست که سرعت بالاتری داره ولی باید SQL بیشتری بنویسی. EF Core راحت‌تر و پرامکانات‌تره. برای پروژه‌های معمولی EF Core بهتره. برای کوئری‌های بسیار پیچیده و حساس به سرعت، می‌تونی از هر دو همزمان استفاده کنی.

آیا می‌تونم EF Core رو با MySQL یا PostgreSQL استفاده کنم؟

کاملاً! EF Core از چندین دیتابیس پشتیبانی می‌کنه. برای MySQL از Pomelo.EntityFrameworkCore.MySql، برای PostgreSQL از Npgsql.EntityFrameworkCore.PostgreSQL و برای SQLite از Microsoft.EntityFrameworkCore.Sqlite استفاده کن. فقط کافیه Provider رو عوض کنی، بقیه کد تغییری نمی‌کنه.

چطور می‌تونم کوئری‌های EF Core رو Debug کنم و ببینم چه SQL‌ای اجرا می‌شه؟

چند روش داری: ۱) از LogTo در تنظیمات DbContext استفاده کن تا SQL ها در Console لاگ بشه. ۲) از SQL Server Profiler یا Azure Data Studio استفاده کن. ۳) در EF Core 5+، متد ToQueryString() رو روی IQueryable فراخوانی کن تا SQL تولیدی رو ببینی. ۴) ابزار MiniProfiler برای وب خیلی مفیده.

Soft Delete در EF Core چطور پیاده‌سازی می‌شه؟

بهترین روش استفاده از Global Query Filter هست. یک فیلد IsDeleted به Entity ات اضافه کن، بعد در DbContext با modelBuilder.Entity.HasQueryFilter(x => !x.IsDeleted) تنظیم کن. از این به بعد EF Core به‌طور خودکار رکوردهای حذف‌شده رو از کوئری‌ها حذف می‌کنه. برای Override کردن این فیلتر از IgnoreQueryFilters() استفاده کن.

آیا EF Core رو با ASP.NET Core Web API می‌تونم استفاده کنم؟

قطعاً! EF Core و ASP.NET Core Web API عالی با هم کار می‌کنن. EF Core رو از طریق Dependency Injection ثبت می‌کنی، بعد از طریق Constructor Injection در Repository یا Service هات ازش استفاده می‌کنی. این ترکیب رایج‌ترین استک برنامه‌نویسی بک‌اند در دنیای .NET هست.

نظرات کاربران