1

为了支持流行的数据库,如sqlserver、oracle和mysql,我们将原始的sql条件Query()方法更改为来自DapperExtension的GetList()方法,但是使用GetList()时会出现性能问题,似乎它会首先读取全表而不是 sql 查询。

  1. sql查询方法:

         TaskViewEntity taskView = null;
         string sql = @"SELECT
                         * 
                      FROM vwWfActivityInstanceTasks 
                      WHERE ActivityInstanceID=@activityInstanceID
                         AND ProcessInstanceID=@processInstanceID
                     ";
    
         var list = Repository.Query<TaskViewEntity>(sql,
         new
         {
             processInstanceID = processInstanceID,
             activityInstanceID = activityInstanceID
    
         }).ToList();
    
  2. linq 方法:

    var sqlQuery = (from tv in Repository.GetAll<TaskViewEntity>(conn, trans)
                            where tv.ActivityInstanceID == activityInstanceID
                                && tv.ProcessInstanceID == processInstanceID
                            select tv
                            );
    var list = sqlQuery.ToList<TaskViewEntity>();
    
    
        //The dapper extension GetList() method
        public IEnumerable<T> GetAll<T>(IDbConnection conn, IDbTransaction trans) where T : class
        {
            var dataList = conn.GetList<T>(null, null, trans);
            return dataList;
        }
    

4

1 回答 1

1

让我们看看你的 LINQ 方法,在这里:

var sqlQuery = (from tv in Repository.GetAll<TaskViewEntity>(conn, trans)
                where tv.ActivityInstanceID == activityInstanceID
                    && tv.ProcessInstanceID == processInstanceID
                select tv);

现在:关于 LINQ 的问题在于它在很大程度上取决于它所使用的. 您似乎期望它将其组合成带有附加where子句的 SQL 查询,以发送到数据库。但是,这不是我们在这里所拥有的;GetAll返回一个IEnumerable<T>,并且 LINQIEnumerable<T>只处理它找到的数据。在 的情况下where,我们可以自己写(为了说明)简单地:

public static IEnumerable<T> Where(this IEnumerable<T> source, Func<T, bool> predicate)
{
    foreach (var obj in source)
    {
        if (predicate(obj))
        {
            yield return obj;
        }
    }
}

实际的实现稍微有点细微差别,但是:不多——而且它基本上仍然在做同样的事情:在输入到达内存时接受输入,测试它们,然后生成它们。

要执行您想要的操作,需要类似 的东西IQueryable<T>,它代表一个可组合的查询。编写IQueryable<T>提供程序非常非常困难,并且远远超出了 Dapper 试图提供的功能。我怀疑GetList<T>您正在使用的方法(它不是Dapper 本身的一部分)也没有提供这个 - 它可能只是将数据作为List<T>. 所以:没有查询组合发生 - 你只是通过网络获取所有内容,然后在本地过滤它。

我在这里强烈建议的是:如果您想要为您构建 SQL 查询的查询组合(使用whereorder by),请使用 ORM - 例如实体框架、LLBLGen 或任何其他。这并不意味着您不能在满足您的需求时也使用 Dapper。这些只是工具。您可以选择多种工具,并在其擅长的地方使用每个工具。您无需在工作开始时选择一种工具并将其用于所有事情。我很容易在同一个项目中同时使用 Dapper 和 EF,并且我编写了 Dapper

于 2021-10-19T12:18:55.203 回答