2014-02-20 19 views
2

的组合的一些问题我一直在试验用于处理业务逻辑的轻量级解决方案。它包含一个以Dapper扩展的vanilla ADO.NET连接,并由Glimpse.ADO进行监视。此设置的用例将是一个Web应用程序,它必须按请求异步处理少数几个查询。在MVC控制器中简单实现我的设置。有关ADO.NET,Dapper QueryAsync和Glimpse.ADO

public class CatsAndDogsController : Controller 
{ 
    public async Task<ActionResult> Index() 
    { 
     var fetchCatsTask = FetchCats(42); 
     var fetchDogsTask = FetchDogs(true); 
     await Task.WhenAll(fetchCatsTask, fetchDogsTask); 
     ViewBag.Cats = fetchCatsTask.Result; 
     ViewBag.Dogs = fetchDogsTask.Result; 
     return View(); 
    } 

    public async Task<IEnumerable<Cat>> FetchCats(int breedId) 
    { 
     IEnumerable<Cat> result = null; 
     using (var connection = CreateAdoConnection()) 
     { 
      await connection.OpenAsync(); 
      result = await connection.QueryAsync<Cat>("SELECT * FROM Cat WHERE BreedId = @bid;", new { bid = breedId }); 
      connection.Close(); 
     } 
     return result; 
    } 

    public async Task<IEnumerable<Dog>> FetchDogs(bool isMale) 
    { 
     IEnumerable<Dog> result = null; 
     using (var connection = CreateAdoConnection()) 
     { 
      await connection.OpenAsync(); 
      result = await connection.QueryAsync<Dog>("SELECT * FROM Dog WHERE IsMale = @im;", new { im = isMale }); 
      connection.Close(); 
     } 
     return result; 
    } 

    public System.Data.Common.DbConnection CreateAdoConnection() 
    { 
     var sqlClientProviderFactory = System.Data.Common.DbProviderFactories.GetFactory("System.Data.SqlClient"); 
     var dbConnection = sqlClientProviderFactory.CreateConnection(); 
     dbConnection.ConnectionString = "SomeConnectionStringToAwesomeData"; 
     return dbConnection; 
    } 
} 

我对在CreateAdoConnection()方法中创建连接有一些疑问。我认为以下是幕后发生的事情。

sqlClientProviderFactory.CreateConnection()的调用返回System.Data.SqlClient.SqlConnection的实例作为System.Data.Common.DbConnection传递。此时Glimpse.ADO.AlternateType.GlimpseDbProviderFactoryGlimpse.Ado.AlternateType.GlimpseDbConnection的实例中启动并包装此连接,该实例也作为System.Data.Common.DbConnection传递。最后,这个连接由Dapper库以其查询方法间接扩展,其中有QueryAsync<>()方法用于提取猫和狗。

的问题:

  1. 是上面的假设是正确的?
  2. 如果我通过此连接使用Dapper的异步方法 - 或者使用此连接的CreateCommand()方法创建System.Data.Common.DbCommand并使用它的异步方法 - 那么这些内部调用总是最终使用这些方法的vanilla异步实现,就像Microsoft为它们编写的那样System.Data.SqlClient.SqlConnectionSystem.Data.SqlClient.SqlCommand?而不是这些方法实际阻塞的其他实现?
  3. 与此设置相比,直接返回新的System.Data.SqlClient.SqlConnection会损失多少perf? (因此,没有Glimpse.ADO包装)
  4. 有关改进此设置的任何建议?

回答

2
  1. 是的非常多。 GlimpseDbProviderFactory包装/装饰/代理所有注册的工厂。然后,我们将所有的调用传递给我们包装的工厂(在这种情况下为SQL Server)。在CreateConnection()的情况下,我们要求我们的内部工厂创建连接,当我们获得该连接时,我们将其包装并将其返回给始发呼叫者
  2. 是的。掠影不会将什么是异步请求转变为阻止请求。尽管如此,我们仍然坚持异步链。如果你有兴趣,有问题的代码是here
  3. 很少。实质上,像这样使用装饰器模式只会向调用堆栈添加一个或两个帧。与请求生命周期中执行的大多数操作相比,观察此处发生的事情的时间极少。
  4. 你看起来不错。只有建议可能是我们this代码来建立工厂。这段代码意味着你可以将你的连接字符串等转移到web.config中。