c# - DbContext 可以组合而不是继承吗?

标签 c# asp.net asp.net-mvc entity-framework simple-injector

假设我正在为一所学校进行代码优先开发,并且我有一个 SchoolDbContext。大多数关于 Entity Framework 的文档都建议您从 DbContextderive:

public class SchoolDbContext : DbContext
{
    public IDbSet<Student> Students => Set<Student>();
}

但我的论点是 SchoolDbContext 从来都不是 DbContext 的特化,它只是利用了 DbContext 所以在我看来,SchoolDbContext 应该DbContext 组成:

public class SchoolDbContext
{
    private readonly DbContext _dbContext;

    public SchoolDbContext(DbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public IDbSet<Student> Students => _dbContext.Set<Student>();
}

在我的 ASP.NET MVC 应用程序的组合根目录中,我通过设置依赖项来尝试这种组合方法(以 Simple Injector 为例):

private static void RegisterDependencies(Container container)
{
     // Assume I have a connection string SchoolDbContext
     container.Register(() => new DbContext("SchoolDbContext"), Lifestyle.Scoped);
     container.Register<SchoolDbContext>(Lifestyle.Scoped);
}

网络配置:

<connectionStrings>
    <add name="SchoolDbContext"
         providerName="System.Data.SqlClient"
         connectionString="Server=(localdb)\MSSQLLocalDB;Integrated Security=true"/>
</connectionStrings>

当我尝试加载 Students 时失败:

The entity type Student is not part of the model for the current context.

当我将其改回继承方法(即调用默认构造函数 new SchoolDbContext())时,一切正常。

Entity Framework 不支持我的组合方法吗?

最佳答案

Can DbContext be composed instead of inherited?

简短回答:

引用官方文档中的备注(重点是我的)

DbContext is usually used with a derived type that contains DbSet<TEntity> properties for the root entities of the model. These sets are automatically initialized when the instance of the derived class is created....

还有很多,但太多了,无法放入这个答案。

来源DbContext Class

Is my composition approach not supported by Entity Framework?

如果您查看 DbContext 的源代码有一些内部方法可以在类中搜索 DbSet s 并初始化它们。

主要是这一段代码

/// <summary>
///     Initializes the internal context, discovers and initializes sets, and initializes from a model if one is provided.
/// </summary>
private void InitializeLazyInternalContext(IInternalConnection internalConnection, DbCompiledModel model = null)
{
    DbConfigurationManager.Instance.EnsureLoadedForContext(GetType());

    _internalContext = new LazyInternalContext(
            this, internalConnection, model
            , DbConfiguration.GetService<IDbModelCacheKeyFactory>()
            , DbConfiguration.GetService<AttributeProvider>());
    DiscoverAndInitializeSets();
}

/// <summary>
///     Discovers DbSets and initializes them.
/// </summary>
private void DiscoverAndInitializeSets()
{
    new DbSetDiscoveryService(this).InitializeSets();
}

您尝试获取的任何模型都会抛出相同的错误,因为该模型在初始化时不是上下文的一部分,这只有在它是派生类的成员时才会发生。

DbContext source code on Github

关于c# - DbContext 可以组合而不是继承吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42569167/

相关文章:

c# - SharePoint 2010如何弹出消息框

c# - 如何使用日期时间选择器

c# - C#多线程服务器-通用客户端集合可能是一个问题

asp.net-mvc - Controller httpresponsemessage 好的,但是ajax总是触发fail方法

asp.net-mvc - Controller 能完全取代 http handler 的功能吗?

c# - ListView 中的图像质量差

asp.net - 如何使用流畅的 nhibernate (schemaexport) 测试生成表?在 asp.net 上下文中

asp.net - 尽管启用了 SSL,但获取 "Firefox can’ t 建立与本地主机服务器的连接

c# - 执行Response.Redirect时如何修改Request.Headers ["Referer"]?

asp.net-mvc - 为什么清除模型后文本框不清除