在哪里处置在AddDbContext中创建的SqlConnection对象的好地方? (.Net Core 2.2)

时间:2019-06-13 10:00:36

标签: c# asp.net-core entity-framework-core

我正在尝试使Azure的托管身份验证与我将在Azure App Service上部署以连接到Azure SQL Server的应用一起使用。

浏览了一些示例和示例代码后,我尝试以下实现:

services.AddDbContext<MainContext>(optionsBuilder =>
{
    SqlConnection connection = new SqlConnection();
    connection.ConnectionString = Configuration.GetConnectionString("DefaultConnection");
    connection.AccessToken = (new AzureServiceTokenProvider()).GetAccessTokenAsync("https://database.windows.net/").Result;

    optionsBuilder.UseSqlServer(connection);
});

在哪里可以处置此SqlConnection?有没有更好的方法来实现此AccessToken设置?

2 个答案:

答案 0 :(得分:2)

您可以尝试先正常注册上下文:

services.AddDbContext<MainContext>(builder => 
               builder.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

根据documentation,默认情况下此地址注册为“作用域”,因此将根据每个请求自动打开和关闭连接。

  

AddDbContext扩展方法向DbContext类型注册一个   默认范围内的生存期。

然后,检索注册的上下文并按如下所示添加访问令牌:

services.AddScoped<MainContext>(serviceProvider => {
      var dbContext = serviceProvider.GetRequiredService<MainContext>();  
      var connection = dbContext.Database.GetDbConnection() as SqlConnection;
      if(connection == null) {
          return dbContext;
      }
      connection.AccessToken = (new AzureServiceTokenProvider()).GetAccessTokenAsync("https://database.windows.net/").Result;
      return dbContext;
});

现在,根据每个请求,将为您创建并释放连接,并且将检索访问令牌。

另一种方式(也许更干净)是从上下文继承并在构造函数中添加令牌:

public class ContextWithAccessToken : MainDbContext 
{
    public ContextWithAccessToken(DbContextOptions options) : base(options)
    {
        var connection = (SqlConnection)this.Database.GetDbConnection();
        connection.AccessToken = (new AzureServiceTokenProvider()).GetAccessTokenAsync("https://database.windows.net/").Result;
    }
}

然后只需注册此上下文:

services.AddDbContext<ContextWithAccessToken>(builder => 
               builder.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

答案 1 :(得分:0)

您不需要处理连接。它针对DbContext附加/配置,并且上下文管理处置。您在那里所拥有的应该可以正常工作。