2014-02-20 28 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中。