【问题标题】:Load EF Core 2 DbContext from dynamically imported DLL从动态导入的 DLL 加载 EF Core 2 DbContext
【发布时间】:2018-11-09 03:23:32
【问题描述】:

我有一个 DbContext 我需要从 DLL 动态加载,因为 Db 上下文会发生变化并且需要在应用程序运行时进行编辑,但是我似乎无法创建这个上下文的实例,因为我似乎需要传递上下文选项。这段代码如下。

Assembly reporting = Assembly.LoadFile(pathString);

        var defaultContext = reporting.GetType("Reporting.DefaultContext");
        var dbContext = Activator.CreateInstance(defaultContext, new
 object[] { /*need to pass in the contructor here*/ }) as DbContext;

而且我编译的上下文是相当标准的,下面这个的修改版本供参考

public class DefaultContext : DbContext
{
    public DefaultContext(DbContextOptions<DefaultContext> options)
        : base(options)
    { }

    public virtual DbSet<Student> Students { get; set; }
    public virtual DbSet<Course> Courses { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Student>().ToTable("Students ", "core")
            .AllProperties().ForEach(x => x.IsRequired());

        modelBuilder.Entity<Course>().ToTable("Courses", "core")
            .AllProperties().ForEach(x => x.IsRequired());
    }
}

在反思方面我非常缺乏经验 - 所以问题确实如此;

这是尝试实现这一目标的最佳方式,还是我应该创建一个方法来调用 DLL 以返回上下文?

如果没有上下文,我该如何传递 DbContextOptions 的实例?

旁注,这是一个 Asp.Net Core 2.0 MVC 项目。

编辑:当将一个空的 obj 数组传递给创建实例时,如下所示,我得到一个缺少的方法异常(未找到构造函数)

var dbContext = Activator.CreateInstance(defaultContext, new object[] { new object[0] }) as DbContext;

而如果我不传入第二个 obj 参数,我会得到相同的异常,但会显示消息“没有为此对象定义无参数构造函数”,所以现在我很迷茫,因为显然有一个构造函数。

【问题讨论】:

    标签: c# entity-framework-core asp.net-core-2.0 system.reflection ef-core-2.0


    【解决方案1】:

    基本上问题是如何通过反射创建/获取DbContextOptions&lt;DefaultContext&gt; 实例。您可以通过首先通过MakeGenericType 构造一个泛型类型,然后将该类型用作Activator.CreateInstance 的参数来做到这一点。

    所以有

    var dbContextType = reporting.GetType("Reporting.DefaultContext");
    

    类似这样的:

    var optionsType = typeof(DbContextOptions<>).MakeGenericType(dbContextType);
    var options = (DbContextOptions)Activator.CreateInstance(optionsType);
    var dbContext = (DbContext)Activator.CreateInstance(dbContextType, options);
    

    然而,DbContextOptions&lt;TDbContext&gt; options 构造函数参数的全部目的是允许从外部配置数据库上下文(如数据库提供程序、连接字符串等),而不是在 OnModelConfiguring 内部进行自我配置,在这种情况下您的派生db context 只会有无参数的构造函数。

    因此最好创建DbContextOptionsBuilder&lt;DefaultContext 实例,使用Fluent APi 对其进行配置,然后将Options 属性(这是预期的DbContextOptions&lt;DefaultContext 类型)传递给DefaultContext 构造函数。例如

    var optionsBuilderType = typeof(DbContextOptionsBuilder<>).MakeGenericType(dbContextType);
    var optionsBuilder = (DbContextOptionsBuilder)Activator.CreateInstance(optionsBuilderType);
    
    string connectionString = ...;
    optionsBuilder.UseSqlServer(connectionString);
    
    var dbContext = (DbContext)Activator.CreateInstance(dbContextType, optionsBuilder.Options);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-16
      • 2018-04-19
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      相关资源
      最近更新 更多