让我们说我正在为学校进行代码优先开发,我有一个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()
)时,一切都运行良好。
实体框架不支持我的构图方法吗?
答案 0 :(得分:5)
可以组合DbContext而不是继承吗?
简短回答:否
引用官方文件(强调我的)的评论
DbContext
通常与包含的派生类型一起使用 模型的根实体的DbSet<TEntity>
属性。 这些 当派生的实例时,集合会自动初始化 创建了类 ....
还有更多,但这个答案太多了。
实体框架不支持我的构图方法吗?
如果查看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();
}
您尝试获取的任何模型都会抛出相同的错误,因为模型在初始化时不是上下文的一部分,只有当它是派生类的成员时才会发生。