در توسعه برنامه‌های مبتنی بر Entity Framework Core، یکی از خطاهای رایجی که ممکن است هنگام اجرای دستورات migration یا scaffold در کنسول مواجه شوید، پیام خطای زیر است:
کینگتو - آموزش برنامه نویسی تخصصصی - دات نت - سی شارپ - بانک اطلاعاتی و امنیت

حل مشکل EF Core: Unable to create an object of type 'YourDbContext' در زمان طراحی به همراه مثال کامل

28 بازدید 0 نظر ۱۴۰۴/۰۲/۲۶

عنوان: حل مشکل 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 استفاده می‌کند:

  1. استفاده از DI (dependency injection) در پروژهٔ اصلی

  2. استفاده از IDesignTimeDbContextFactory

  3. استفاده از یک سازنده بدون پارامتر (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 باید با دقت بیشتری تنظیم شود.

لینک استاندارد شده: 8kb

0 نظر

    هنوز نظری برای این مقاله ثبت نشده است.