【问题标题】:Can take be used in a query expression in c# linq instead of using .Take(x)?可以在 c# linq 的查询表达式中使用 take 而不是使用 .Take(x) 吗?
【发布时间】:2008-10-31 16:25:14
【问题描述】:

我正在尝试编写一些可以生成类似 SQL 的 LINQ To SQL 代码

SELECT t.Name, g.Name
FROM Theme t
INNER JOIN (
    SELECT TOP 5 * FROM [Group] ORDER BY TotalMembers
) as g ON t.K = g.ThemeK

目前为止

var q = from t in dc.Themes 
join g in dc.Groups on t.K equals g.ThemeK into groups 
select new { 
    t.Name, Groups = (from z in groups orderby z.TotalMembers select z.Name )
};

但我需要对有序组子查询进行顶部/获取。根据 VB 中的http://blogs.msdn.com/vbteam/archive/2008/01/08/converting-sql-to-linq-part-7-union-top-subqueries-bill-horst.aspx,我可以在最后添加 TAKE 5,但我无法在 c# 中使用此语法。 c#中的take语法如何使用?

编辑:PS 在末尾添加 .Take(5) 会导致它运行大量单独的查询

编辑 2:我对上述 SQL 的意图犯了一个小错误,但问题仍然存在。 问题在于,如果您在查询中使用扩展方法,例如 .Take(5),LinqToSql 会运行大量 SQL 查询而不是单个查询。

【问题讨论】:

  • 在回答问题时更新/编辑您的问题和/或在答案中添加 cmets 是一种更好的做法。这样一来,您的个人资料中就不会出现大量虚假答案。

标签: c# linq linq-to-sql


【解决方案1】:

第二个答案,现在我重读了原来的问题。

您确定您显示的 SQL 实际上是正确的吗?它不会给出每个主题中的前 5 个组 - 它只会将每个主题与前 5 个组进行匹配总体

简而言之,如果您使用以下方法,我怀疑您会得到原始 SQL:

var q = from t in dc.Themes 
join g in dc.Groups.OrderBy(z => z.TotalMembers).Take(5)
  on t.K equals g.ThemeK into groups 
select new { t.Name, Groups = groups };

但我认为这不是你真正想要的......

【讨论】:

    【解决方案2】:

    只需将您的查询表达式括起来并调用它:

    var q = from t in dc.Themes 
    join g in dc.Groups on t.K equals g.ThemeK into groups 
    select new { t.Name, Groups = 
           (from z in groups orderby z.TotalMembers select z.Name).Take(5) };
    

    事实上,查询表达式并没有真正让事情变得更简单——你不妨直接调用 OrderBy:

    var q = from t in dc.Themes 
    join g in dc.Groups on t.K equals g.ThemeK into groups 
    select new { t.Name, Groups = groups.OrderBy(z => z.TotalMembers).Take(5) };
    

    【讨论】:

      【解决方案3】:

      这是对原始查询的忠实翻译。这不应产生重复的往返。

      var subquery =
        dc.Groups
        .OrderBy(g => g.TotalMembers)
        .Take(5);
      
      var query =
        dc.Themes
        .Join(subquery, t => t.K, g => g.ThemeK, (t, g) => new
        {
          ThemeName = t.Name, GroupName = g.Name
        }
        );
      

      问题中的往返是由 groupjoin(加入)引起的。 LINQ 中的组具有层次结构。 SQL 中的组具有行/列形状(分组键 + 聚合)。为了让 LinqToSql 从行/列结果填充其层次结构,它必须使用组的键单独查询子节点。仅当子级在聚合之外使用时才会这样做。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-16
        • 2014-02-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多