可以组成DbContext而不是继承吗?

时间:2017-03-03 01:43:00

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

让我们说我正在为学校进行代码优先开发,我有一个SchoolDbContext。大多数有关实体框架的文档都建议您从DbContext 派生

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);
}

的Web.config:

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

当我尝试使用以下代码加载Students时失败

  

实体类型Student不是当前上下文模型的一部分。

当我将其更改回继承方法(即调用默认构造函数new SchoolDbContext())时,一切都运行良好。

实体框架不支持我的构图方法吗?

1 个答案:

答案 0 :(得分:5)

  

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

简短回答:

引用官方文件(强调我的)的评论

  

DbContext通常与包含的派生类型一起使用   模型的根实体的DbSet<TEntity>属性。 这些   当派生的实例时,集合会自动初始化   创建了类 ....

还有更多,但这个答案太多了。

来源DbContext Class

  

实体框架不支持我的构图方法吗?

如果查看DbContext的源代码,可以使用内部方法在类中搜索DbSet并初始化它们。

主要是这段代码

/// <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