关于ADO.NET,Dapper QueryAsync和Glimpse.ADO组合的一些问题

时间:2014-02-20 17:22:54

标签: asp.net ado.net dapper glimpse

我一直在尝试使用轻量级解决方案来处理我的业务逻辑。它由一个vanilla ADO.NET连接组成,该连接使用Dapper进行扩展,并由Glimpse.ADO监视。此设置的用例将是一个Web应用程序,它必须按请求异步处理少量查询。下面是MVC控制器中我的设置​​的简单实现。

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.GlimpseDbProviderFactory启动并将此连接包装在Glimpse.Ado.AlternateType.GlimpseDbConnection的实例中,该实例也作为System.Data.Common.DbConnection传递。最后,这个连接由Dapper库以及查询方法间接扩展,其中包括用于获取猫和狗的QueryAsync<>()方法。

问题:

  1. 上述假设是否正确?
  2. 如果我在此连接中使用Dapper的异步方法 - 或者使用此连接的System.Data.Common.DbCommand方法创建CreateCommand(),并使用它的异步方法 - 那些内部调用总是会使用vanilla异步实现Microsoft为System.Data.SqlClient.SqlConnectionSystem.Data.SqlClient.SqlCommand撰写的这些方法是什么?而这些方法的其他实现并没有实际阻塞吗?
  3. 与仅直接返回新System.Data.SqlClient.SqlConnection相比,此设置会丢失多少穿孔? (所以,没有Glimpse.ADO包装器)
  4. 有关改进此设置的任何建议吗?

1 个答案:

答案 0 :(得分:2)

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