当子类不添加任何额外的逻辑时,为什么我需要覆盖父类dbcontext的构造函数?

发布于 2025-02-07 12:17:17 字数 2727 浏览 2 评论 0原文

我已经创建了一个microsoft.entityframeworkcore.dbcontext(称为AppContext)的子类,并且我正在我的测试类中创建一个AppContext的实例。

我已经在appContext中添加了一个空构造函数,以解决构建错误:cs1729'appContext'不包含使用1个参数的构造函数。我不知道为什么需要这样做。

父类dbContext似乎具有一个构造函数,该构造函数采用单个参数microsoft.entityframeworkcore.dbcontextoptions。当我调用AppContext的构造函数时,我将传递一个类型dbContextOptions< appContext>的参数。

AppContext:

using Microsoft.EntityFrameworkCore;
using OMSBackend.Models;

namespace OMSBackend
{
    public class AppContext : DbContext
    {
        // A build error occurs if I comment out this constructor.
        public AppContext(DbContextOptions options) : base(options)
        {
        }

        public DbSet<User> Users { get; set; }
    }
}

inmemorydatabasetestbase:(

using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;

namespace OMSBackend.Tests.Unit
{

    public abstract class InMemoryDatabaseTestBase : IDisposable
    {
        private DbContextOptions<AppContext> _contextOptions;
        private SqliteConnection _connection;

        protected InMemoryDatabaseTestBase()
        {
            _connection = OpenInMemorySqliteConnection();
            _contextOptions = new DbContextOptionsBuilder<AppContext>()
                .UseSqlite(_connection)
                .Options;
        }

        public void Dispose()
        {
            _connection.Dispose();
        }

        protected AppContext CreateContext()
        {
            return new(_contextOptions);
        }

        private SqliteConnection OpenInMemorySqliteConnection() {
            _connection = new SqliteConnection("Filename=:memory:");
            _connection.Open();
            return _connection;
        }
    }
}

使用语句存在,因为我已经禁用了我的项目中的隐式。)

我是C#的新手需要在此处覆盖构造函数。我是否忽略了一些东西,可以让我在不覆盖构造函数的情况下扩展dbContext

我已经使用这些文章作为指导:

https://learn.microsoft.com/en-us/ef/core/core/testing/testing-without-theout-the-database#sqlite-sqlite-in-memory

https://www.meziantou.net/testing-ef-pesting-ef-core-ing-core-in-memory -using-sqlite.htm (gérald的sampledbcontext类也像我必须做的那样覆盖构造函数。)

I've created a subclass of Microsoft.EntityFrameworkCore.DbContext (called AppContext) and I am creating an instance of AppContext in my test class.

I've added an empty constructor to AppContext to resolve a build error: CS1729 'AppContext' does not contain a constructor that takes 1 arguments. I can't figure out why I need to do this.

The parent class DbContext appears to have a constructor that takes a single argument of type Microsoft.EntityFrameworkCore.DbContextOptions. When I call the constructor for AppContext I'm passing an argument of type DbContextOptions<AppContext>.

AppContext:

using Microsoft.EntityFrameworkCore;
using OMSBackend.Models;

namespace OMSBackend
{
    public class AppContext : DbContext
    {
        // A build error occurs if I comment out this constructor.
        public AppContext(DbContextOptions options) : base(options)
        {
        }

        public DbSet<User> Users { get; set; }
    }
}

InMemoryDatabaseTestBase:

using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;

namespace OMSBackend.Tests.Unit
{

    public abstract class InMemoryDatabaseTestBase : IDisposable
    {
        private DbContextOptions<AppContext> _contextOptions;
        private SqliteConnection _connection;

        protected InMemoryDatabaseTestBase()
        {
            _connection = OpenInMemorySqliteConnection();
            _contextOptions = new DbContextOptionsBuilder<AppContext>()
                .UseSqlite(_connection)
                .Options;
        }

        public void Dispose()
        {
            _connection.Dispose();
        }

        protected AppContext CreateContext()
        {
            return new(_contextOptions);
        }

        private SqliteConnection OpenInMemorySqliteConnection() {
            _connection = new SqliteConnection("Filename=:memory:");
            _connection.Open();
            return _connection;
        }
    }
}

(The using statements are present because I've disabled ImplicitUsings in my project.)

I'm new to C#, but it seems like I shouldn't need to override the constructor here. Is there something I've overlooked that would allow me to extend DbContext without overriding the constructor?

I've used these articles as a guide:

https://learn.microsoft.com/en-us/ef/core/testing/testing-without-the-database#sqlite-in-memory

https://www.meziantou.net/testing-ef-core-in-memory-using-sqlite.htm (Gérald's SampleDbContext class also overrides the constructor, as I've had to do.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

世界如花海般美丽 2025-02-14 12:17:17

类不会自动从其基类继承构造函数。除默认(无参数)构造函数以外的所有类的构造函数都必须在该类中实现。您实际上并没有在该代码中覆盖任何内容。您正在派生的类中实现新的构造函数,并在基类中调用构造函数。派生的构造函数通常会调用具有相同参数的基本构造函数,但不必这样做。

A class doesn't automatically inherit a constructor from its base class. All constructors for a class, other than the default (parameterless) constructor, must be implemented in that class. You aren't actually overriding anything in that code. You are implementing a new constructor in your derived class and that invokes a constructor in the base class. A derived constructor will often invoke a base constructor with the same parameters but it doesn't have to do so.

梦屿孤独相伴 2025-02-14 12:17:17

如果您没有调用构造函数,那么访问类型成员的行为将无法很好地定义。因此,作为适用于所有面向对象的编程语言的一般规则,在构建类时,您必须首先构造基类的有效实例。

C#编译器将帮助您处理无参数构造函数的常见情况以几种方式

  • 如果基类具有无参数构造函数,则将被隐式称为。
  • 如果您没有提供任何明确的构造函数,则编译器将为您生成无参数构造函数。

If you haven't called a constructor, then the behaviour of accessing a member of a type wouldn't be well defined. So as a general rule that applies to all Object Oriented programming languages, when constructing a class you must first construct a valid instance of your base class.

The C# compiler will help you handle the common case of parameter-less constructors in a couple of ways.

  • if the base class has a parameter-less constructor, it will be called implicitly.
  • if you haven't provided any explicit constructors, the compiler will generate a parameter-less constructor for you.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文