从dapper结果中调用每条记录上的函数

asp.net-mvc-5 c# dapper

我试图在每个记录上调用一个函数来设置一些字段值。如果要对结果进行分页,则可通过以下方式实现:

public IDataWrapper GetPagedQuery<T>(string myQuery, object param, Action<T> customAction)
{
    var obj = new DataWrapper ();
    using (var oConn = CreateConnection(ConnectionString))
    {
        TotalPages totalRows = null;
        var list = oConn.Query<T, TotalPages, T>(myQuery, (e, t) =>
        {
            totalRows = t;
            if (mapAction != null) customAction(e);
            return e;
        }, param, splitOn: "SplitOn");
        obj.RowsFound = (IEnumerable<dynamic>)list;
        obj.TotalRows = totalRows == null ? 0 : totalRows.TotalRows;
    }
    return obj;
}

当结果不打算被分页时,我的问题出现了。我在第一个示例中的查询包括拆分列,这就是为什么它一切正常,但是我的下一个查询是一个简单的查询,例如Select Column1, Column2 FROM MyAwesomeTable ,它将返回所有行,列等...

问题是我仍然需要对返回的每个结果应用customAction。现在让我们想象一下,有可能有几百万条记录回来(相信我,根据我的情况,这不是不切实际的),因此我不想再次循环遍历每条记录并应用我的方法,我想要那种方法应用作为短小精悍的人返回结果,就像在第一种情况下一样。

这是我尝试过的:

public IDataWrapper GetNonPagedQuery<T>(string myQuery, object param, Action<T> customAction)
{
    var obj = new DataWrapper ();
    using (var oConn = CreateConnection(ConnectionString))
    {
        var list = oConn.Query<T>(myQuery, (e) =>
        {
            if (mapAction != null) customAction(e);
            return e;
        }, param).ToList();
        obj.RowsFound = (IEnumerable<dynamic>)list;
        obj.TotalRows = list.Count();
    }
    return obj;
}

我收到上述代码的错误,它无法解析方法Query<T>(etc...我明白这是因为它不存在。我在这里问什么是最好的方法来完成我想要做的事情?是否有可能与短小精悍。

一般承认的答案

我担心简短的回答是你不能这样做。

稍微长一点的答案是,在您的分页查询中,它本质上第二次传递数据,因为Dapper做了一些工作将每行的数据转换为“T”的实例,然后它单独调用“map”方法您用来调用“customAction”。

因此,在执行简单的非分页“conn.Query”调用之后,执行customAction的后续传递之间几乎没有什么区别。类似于以下内容:

public IDataWrapper GetNonPagedQuery<T>(string myQuery, object param, Action<T> customAction)
{
    var obj = new DataWrapper();
    using (var oConn = CreateConnection(ConnectionString))
    {
        var results = oConn
            .Query<T>(myQuery)
            .ToList();
        obj.TotalRows = results.Count();
        obj.RowsFound = results
            .Select(value =>
            {
                customAction(value);
                return value;
            })
            .Cast<dynamic>();
    }
    return obj;
}

如果你担心的是你可能在非分页查询中加载了很多很多记录,那么值得记住的是, 所有这些记录都将立即加载到内存中;它们不会一次一个地从数据库中提取,因为您对返回的结果进行了枚举,这可能会耗费相当多的资源(如果您要讨论的数据很多,那么您希望避免第二次枚举) 。

这必须是这种情况,因为SQL连接在GetNonPagedQuery返回时关闭,因此无法通过调用者“按需”读取数据。如果您真的在处理大量数据,那么非分页查询可能不是最好的方法吗?

请注意,在上面的代码中,只有在枚举行时才会调用“customAction”,在GetNonPagedQuery返回之前不会触发这些行。如果“customAction”可能是一项昂贵的操作,那么这可能对您有利。另一方面,如果你想在GetNonPagedQuery返回之前为每个结果调用“customAction”,那么在Cast <dynamic>()之后你需要再多一次ToList()调用,它只取决于哪个场景对你更有用。


热门答案

是的,它可能是:

请参阅有关每行类型切换的Dapper文档部分。我怀疑(即我自己没有尝试过)如果你使用相同的系统将结果按照你想要的格式按下来阅读每一行并明确地处理它,它就行不通。



许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因
许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因