具有动态DbContext的Entity Framework 5.0存储库

时间:2013-02-11 22:17:11

标签: entity-framework

如上所述,是否可以创建一个适合用作Entity Framework 5.0 POCO上下文的DbContext实例,其中的属性通常被声明为

public DbSet<T> Entities { get; set; }

直到运行时才设置/知道?

我想创建一个包含

等方法的存储库
public TEntity Find<TEntity>(object key) where TEntity : class
{
    return _context.Set<TEntity>().Find(key);
}

public void Update<TEntity>(TEntity entity) where TEntity : class
{
    if (_context.Entry(entity).State == EntityState.Detached) //entity is detached 
        _context.Set<TEntity>().Attach(entity);
    _context.Entry(entity).State = EntityState.Modified;
}

.... etc

然后使用它们:

Widget w = repository.Find<Widget>(123);
repository.SaveChanges();

如果将存储库的上下文设置为包含DbSet<Widget> Widgets的类,则这是微不足道的,但可以这样做,以便我计划使用的实体类型在运行时才会知道,或者可能直到我实际上使用它们?因此,如果我有一个新类Foo,我可以立即查询我的存储库.Find<Foo>(123),而不必先将DbSet<Foo> Foos添加到我的DbContext类中?

我认为这应该是可能的,因为poco类或DbContext实例没有什么特别之处,它保存了对它们的引用。

1 个答案:

答案 0 :(得分:2)

您的上下文中不需要DbSet<Foo> Foos属性。这只是告诉上下文Foo实体存在的一种方法。上下文发现映射实体的方式有多种:

  • 明确DbSet<T>属性
  • 通过已发现实体中的导航属性
  • 通过在DbModelBuilder中指定映射
    • 在您的上下文类型中覆盖OnModelCreated
    • 手动创建DbModelBuilder,构建它并将其编译为DbCompiledModel,可以传递给DbContext构造函数
    • 为每个实体声明EntityTypeConfiguration<T>并将其添加到DbModelBuilderOnModelCreated或手动创建的DbModelBuilder)。

最后一个选项可用于在应用程序启动时发现所有必需的实体(例如,通过搜索所有实体配置类的程序集并将它们注册到模型构建器),但它仍然不是完全动态的解决方案。当第一次使用上下文时,编译模型通常仅在每次应用程序运行时构造一次。如果不替换已编译的模型,则无法向上下文添加或删除映射的实体类型。