c#-4.0 - 在委托(delegate)、Func 或 Action C# 中推广 Dapper 查询

标签 c#-4.0 generics dapper

我有几种 Dapper像下面这样的查询,结果有几种不同的类型。这是其中一个特定的,它产生例如列表:

string anSql = GetSqlQueryText("query_name");
SqlConnection connection = GetSqlConnection();

List<ClassA> result = null;
try
{
    connection.Open();
    result = connection.Query<ClassA>(anSql, new    //want to move this part from here
    {
        param1 = "value1",
        param2 = "value2"
    }).ToList();                                    //to here out, to an outer call
}
catch //more error handling and retry logic omitted and this is a simplified version
{
    result = new List<ClassA>();       //this good to be filled up by the generic type
}
finally
{
    connection.Close();
}

我想将这种查询加入到 GenDapperQuery 泛型方法中,可以在委托(delegate)(或 Func/Action 或其他任何东西)的帮助下调用该方法,如下所示(T 将是 ClassA 或 ClassB,等在最终代码中):

List<T> result = GenDapperQuery<T>(() =>
{
    result = connection.Query<T>(anSql, new
    {
        param1 = "value1",
        param2 = "value2"
    }).ToList();
}
//and I want to use the result then as a specific type e.g. ClassA
//either immediately or after a cast
result[0].Id = 3; //or
(result as List<ClassA>)[0].Id = 3;

所以我的目的是多次使用连接、我的错误处理/重试逻辑,当然还有 Dapper 查询(因为我不想将它们写下来与我拥有的查询和类型一样多),但我想以某种方式对这个(想要的)通用方法说,用 dapper 查询什么以及创建和填充什么类型的(通用)列表。

(这个(想要的)泛型方法将位于同一个类中,我可以在其中创建一次连接。错误处理部分会更复杂,但每种类型总是相同的,这就是为什么我不想编写它们多次向下。参数可以自由变化,就像sql字符串作为输入一样。)

我现在的问题是,我无法围绕我自己的代码编写通用的 Dapper 查询,而是使用来自此(想要的)方法外部的特定注入(inject)函数。

这在 C# 中可能吗?任何建议将不胜感激。

最佳答案

有很多方法可以实现这一点。一种机制是为 Execute/ErrorHandler 创建一个方法:

public TResult ExecuteWrapper<TResult>(SqlConnection connection, Func<TResult, SqlConnection> func)
{
    TResult result;
    try
    {
        connection.Open();
        // Query will be wrapped in a function or lambda
        result = func(connection);
    }
    catch //more error handling and retry logic omitted and this is a simplified version
    {
        // Specifying a new TResult may be more difficult. You could either:
        // 1. Pass a default value in the method parameter
        //    result = defaultValue; // defaultValue is method parameter
        // 2. Use System.Activator to create a default instance
        //    result = (TResult)System.Activator(typeof(TResult));

        // Original: result = new List<ClassA>(); // this good to be filled up by the generic type
    }
    finally
    {
        connection.Close();
    }
    return result;
}

然后你会像这样使用它:

List<ClassA> result = ExecuteWrapper(connection, (cn) =>
    {
        string anSql = GetSqlQueryText("query_name");
        return cn.Query<ClassA>(anSql, new
            {
                param1 = "value1",
                param2 = "value2"
            }).ToList();        
    });

关于c#-4.0 - 在委托(delegate)、Func 或 Action C# 中推广 Dapper 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17753991/

相关文章:

c# - 基类和条件泛型之间的区别

c# - 泛型 C# 如何通过参数传递泛型对象的属性

java - Java 8 中异常类型推断的一个独特功能

c# - System.Data.SqlClient.SqlConnection 不包含使用 dapper 和 c# 查询的定义

c# - 按值对 ConcurrentDictionary 进行排序

.net - 有关与 .Net 的 ActionScript 套接字通信的帮助

asp.net-mvc - 无法打开项目,因为其项目类型 (.modelProj) 不受支持

c#-4.0 - 将图像发布到 Windows Phone 8 中的 Web 服务器

c# - Dapper 查询列表返回类型

c# - Dapper 的参数化更新和插入?