【发布时间】:2013-06-14 01:11:36
【问题描述】:
假设我有以下简化的 Linq 查询,它将使用 LinqToSQL 对数据库运行:
public IEnumerable<MembershipDto> GetAllUserMemberships()
{
return (from m in _workspace.GetDataSource<UserMembership>()
join g in _workspace.GetDataSource<Group>()
on m.GroupID equals g.GroupID
join u in _workspace.GetDataSource<User>()
on m.UserID equals u.UserID
select
new MembershipDto
{
GroupID = g.GroupID,
GroupName = g.Name,
UserID = u.UserID,
UserName = u.Name
}
).Distinct()
.OrderBy(x => x.GroupName)
.ThenBy(x => x.UserName);
}
出于性能考虑,我希望尽可能多地在生成的 SQL 查询中运行此查询;但是我希望在 Linq 中维护业务逻辑,以便轻松进行单元测试。
我的问题是我不确定上述查询在哪里停止在 SQL 中执行并开始在内存中进行操作。
我的假设是,一旦数据被选入new MembershipDto,它就不再在 SQL 中执行;因此后续的OrderBy()ThenBy()和Distinct()操作发生在内存中。
但是OrderBy() 产生一个IOrderedQueryable 类型的集合而不是IOrderedEnumerable;这向我表明该查询仍可能在 SQL 中完整执行。
我的假设是否正确,或者整个查询是否已转换为 SQL,如果是,为什么会这样?
【问题讨论】:
-
您是否尝试过运行分析器来检查执行的 SQL?它应该可以很好地表明 SQL 执行了多少。
-
"我希望在 Linq 中维护业务逻辑,以便轻松进行单元测试" 1) 无论 Linq 在您的客户端应用程序还是在 SQL 中执行,您的逻辑都是仍然在 Linq 中,所以,2) Linq 的任何选择都不应该对您的单元测试产生任何影响。
-
直到您进行迭代或某事导致迭代,它仍在构造 SQL 语句。你应该没问题
-
@DarrenKopp,函数返回类型 IEnumerable
是否意味着它是退出 L2S 域并进入 L2O 域的点?我认为确实如此,因为 Linq to Sql 查询返回 IQueryable . -
是的,一旦你点击了 IEnumerable,你就处于 linq 2 对象中,这意味着一切都将在内存中完成,但只有在你开始迭代之后。
标签: c# linq linq-to-sql