在Linq操作之前,Dapper是否从数据库请求完整对象?

时间:2017-02-14 20:21:30

标签: sql-server linq dapper dapper-contrib

我一直很好奇Dapper(或许其他ORM)在与LINQ结合使用时如何处理对象检索。

如果我有这样的课程:

public static IEnumerable<SitePage> GetAll()
{
    using (IDbConnection cn = new SqlConnection(g.Global.CONX))
    {
        cn.Open();
        return cn.GetAll<SitePage>();
    }
}

我构建了一个这样的查询:

var result = SitePage.GetAll().Select(c=> new { c.id, c.PageUrl, c.ParentId });

我很好奇,如果在后台,整个记录集被拉入包括所有其他列(可能包含非常大的varchars),或者Dapper从这个查询中理解只是为了从sql请求的列中提取D b?我意识到这有点像新手,但我想更好地理解Dapper / LINQ的互动。

此处发布了一个类似的问题:selecting-specific-columns-using-linq-what-gets-transferred,但我不确定是否已完全回答。海报有两个问题,也没有使用我通常喜欢的lambda表达式。

这个问题的答案会让我的思绪变得更加激动(很可能会改变我的编码方式,因为我一直很谨慎,觉得我通过显式的sql写了太多的代码)。

1 个答案:

答案 0 :(得分:5)

Dapper不会将您的lambda表达式转换为SQL,因此在您的情况下,Dapper生成的SQL查询将返回SitePage的完整实例。

如果查看Dapper GetAll<T>方法的签名,可以快速了解是否属于这种情况。当它返回IEnumerable<T>时,表示它返回T的集合,因此您之后使用的任何运算符(如您的情况中的Select)将应用于完整集合。简而言之,在致电GetAll<T>后,您已不再在Dapper世界。

如果您在过去使用成熟的ORM - 我的意思是更多功能,不一定更好 - 比如Entity Framework或NHibernate,您会注意到某些API返回IQueryable<T>,代表尚未执行的查询。因此,您在IQueryable<T>上使用的运算符(例如SelectWhere)实际上会修改查询。当您通过迭代查询或在其上调用ToListToArray来实现查询时,ORM会将查询表达式树转换为SQL并将该查询发送到数据库。