حل مشکل EF Core: Unable to create an object of type 'YourDbContext' در زمان طراحی به همراه مثال کامل
عنوان: حل مشکل EF Core: Unable to create an object of type 'YourDbContext' در زمان طراحی به همراه مثال کامل
در توسعه برنامههای مبتنی بر Entity Framework Core، یکی از خطاهای رایجی که ممکن است هنگام اجرای دستورات migration یا scaffold در کنسول مواجه شوید، پیام خطای زیر است:
Unable to create an object of type 'YourDbContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
این خطا زمانی رخ میدهد که EF Core نتواند شیء DbContext
موردنظر را در زمان طراحی (Design Time) بسازد. در این مقاله به بررسی دلایل این مشکل و نحوه حل آن با ارائه یک مثال واقعی میپردازیم.
دلایل بروز خطا
Entity Framework Core در زمان اجرای دستورات مانند:
dotnet ef migrations add InitialCreate
یا:
dotnet ef database update
باید بتواند نمونهای از کلاس DbContext
شما را ایجاد کند. این فرآیند در زمان طراحی (design-time) صورت میگیرد، نه در زمان اجرا. برای این منظور، EF Core از چند الگو برای پیدا کردن یا ساختن نمونهای از DbContext
استفاده میکند:
-
استفاده از DI (dependency injection) در پروژهٔ اصلی
-
استفاده از
IDesignTimeDbContextFactory
-
استفاده از یک سازنده بدون پارامتر (parameterless constructor) در DbContext
اگر هیچکدام از این الگوها در پروژه شما پیادهسازی نشده باشد، EF Core نمیتواند شیء DbContext
شما را در زمان طراحی بسازد و خطای بالا را نمایش میدهد.
راه حل: استفاده از Design-Time Factory
بهترین و ایمنترین روش برای حل این مشکل، پیادهسازی کلاس IDesignTimeDbContextFactory
است. در ادامه مراحل پیادهسازی را گام به گام شرح میدهیم.
1. کلاس DbContext خود را ایجاد کنید
فرض کنید کلاس DbContext
شما به شکل زیر است:
public class DataBaseContext : DbContext
{
public DataBaseContext(DbContextOptions options) : base(options) {}
public DbSet Users { get; set; }
public DbSet Messages { get; set; }
}
نکته مهم اینجاست که این کلاس سازنده بدون پارامتر ندارد و وابسته به DbContextOptions
است. در نتیجه EF نمیتواند خودش این کلاس را instantiate کند.
2. ایجاد کلاس DataBaseContextFactory
اکنون باید کلاسی پیادهسازی کنید که از IDesignTimeDbContextFactory
ارثبری کرده و EF Core را در زمان طراحی راهنمایی کند تا بتواند DbContext
شما را بسازد.
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Configuration;
using System.IO;
public class DataBaseContextFactory : IDesignTimeDbContextFactory
{
public DataBaseContext CreateDbContext(string[] args)
{
IConfigurationRoot configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
var optionsBuilder = new DbContextOptionsBuilder();
optionsBuilder.UseSqlServer(configuration.GetConnectionString("DefaultConnection"));
return new DataBaseContext(optionsBuilder.Options);
}
}
نکات مهم:
-
این کلاس معمولاً باید در پروژهای قرار بگیرد که EF Core دستورهای migration روی آن اجرا میشود.
-
مسیر فایل appsettings.json باید صحیح باشد؛ معمولاً در پروژه اصلی قرار دارد.
3. تنظیم connection string در appsettings.json
اطمینان حاصل کنید که فایل appsettings.json
شما دارای بخش ConnectionStrings
است:
{
"ConnectionStrings": {
"DefaultConnection": "Server=.;Database=MyAppDb;Trusted_Connection=True;"
}
}
4. اجرای migration
پس از انجام مراحل بالا، اکنون میتوانید دستورات EF Core را بدون خطا اجرا کنید:
dotnet ef migrations add InitialCreate
یا:
dotnet ef database update
مثال واقعی از پروژه Chat Application
فرض کنید در حال توسعه برنامهای مانند چت هستید. کلاس DbContext
شما به شکل زیر است:
public class DataBaseContext : DbContext, IDataBaseContext
{
public DbSet Users { get; set; }
public DbSet Messages { get; set; }
public DataBaseContext(DbContextOptions options) : base(options) {}
public override int SaveChanges()
{
// مدیریت تاریخ Insert/Update/Delete
}
}
و برای آن یک factory پیادهسازی میکنید:
public class DataBaseContextFactory : IDesignTimeDbContextFactory
{
public DataBaseContext CreateDbContext(string[] args)
{
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
var options = new DbContextOptionsBuilder()
.UseSqlServer(config.GetConnectionString("DefaultConnection"))
.Options;
return new DataBaseContext(options);
}
}
با این پیادهسازی، دیگر مشکلی برای اجرای migration یا scaffold نخواهید داشت.
نتیجهگیری
خطای "Unable to create an object of type 'YourDbContext'" یکی از رایجترین خطاهایی است که توسعهدهندگان EF Core ممکن است با آن مواجه شوند. دلیل این خطا ناتوانی EF در ایجاد نمونهای از کلاس DbContext در زمان طراحی است.
با پیادهسازی IDesignTimeDbContextFactory
و تنظیم صحیح فایل appsettings.json
میتوانید این مشکل را بهطور کامل رفع کرده و کنترل کاملی بر ساختار پروژه و فرآیند طراحی دیتابیس داشته باشید.
منابع مفید:
در صورتی که پروژه شما چند لایهای یا از چند پروژه مختلف تشکیل شده باشد (مانند پروژههای ASP.NET Core)، ساختار مسیر و BasePath در فایل DesignTimeDbContextFactory
باید با دقت بیشتری تنظیم شود.
0 نظر
هنوز نظری برای این مقاله ثبت نشده است.