简体   繁体   English

我在构建Linq查询时做错了什么

[英]what am i doing wrong in constructing Linq query

I am trying to write equivalent linq code for following query. 我正在尝试为后续查询编写等效的linq代码。

SELECT A.*  
FROM  
(  
    SELECT * FROM TableA   
    WHERE id = 100  
) a  
JOIN   
(  
    SELECT Name, MAX(AnotherId) AnotherId   
    FROM TableA   
    WHERE id = 100  
    GROUP BY Name   
) b  
on a.Name  = b.Name and a.AnotherId = b.AnotherId   

This is the linq 这是linq

var Collection = from R in DbContext.TableA  
join G in (DbContext.TableA.Where(r => r.Id == 100).GroupBy(r => new { r.Name, r.AnotherId } ).Select(g => new { Name = g.Name , AnotherId = g.Max(o => o.AnotherId) }))  
on new { R.Name, R.AnotherId } equals new { G.Name, G.AnotherId }  
where R.Id == 100  
select R;  

But I am getting following compilation error that I don't know how to fix. 但我得到以下编译错误,我不知道如何解决。 Any thoughts 有什么想法吗

The type of one of the expressions in the join clause is incorrect. join子句中某个表达式的类型不正确。 Type inference failed in the call to 'Join'. 调用“加入”时类型推断失败。

Error 7 'System.Linq.IGrouping' does not contain a definition for 'Name' and no extension method 'Name' accepting a first argument of type 'System.Linq.IGrouping' could be found (are you missing a using directive or an assembly reference?) 错误7'System.Linq.IGrouping'不包含'Name'的定义,并且没有扩展方法'Name'接受类型'System.Linq.IGrouping'的第一个参数可以找到(你是否缺少using指令或者装配参考?)

You group by r.Name, r.AnotherId, when you just want to group by r.Name. 当您只想按r.Name分组时,按r.Name,r.AnotherId进行分组。

var Collection = from R in DbContext.TableA  
join G in (DbContext.TableA
                      .Where(r => r.Id == 100)
                      .GroupBy(r => r.Name)
                      .Select(g => new { Name = g.Key , AnotherId = g.Max(o => o.AnotherId) }))  
on new { R.Name, R.AnotherId } equals new { G.Name, G.AnotherId }  
where R.Id == 100  
select R; 

And to have all in Fluent Syntax 并使用流利语法

var collection = DbContext.TableA
                          .Where(t1 => t1.Id == 100)
                          .Join(DbContext.TableA
                                .Where(t2 => t2.Id == 100)
                                .GroupBy(t2 => t2.Name)
                                .Select(group => new{Name = group.Key, 
                                                      AnotherId = group.Max(e => e.AnotherId)})
                                 ),
                                 t1 => new{t1.Name, t1.AnotherId} ,
                                 t2 => new{t2.Name, t2.AnotherId},
                                 (t1, t2) => t1);

llHi you need the following syntax, notice the addition of 'Key' llHi你需要以下语法,注意添加'Key'

var Collection = from R in DbContext.TableA  
join G in (DbContext.TableA.Where(r => r.Id == 100)
            .GroupBy(r => new { r.Name, r.AnotherId } )
            .Select(g => new { Name = g.Key.Name , AnotherId = g.Max(o => o.AnotherId) }))  
on new { R.Name, R.AnotherId } equals new { G.Name, G.AnotherId }  
where R.Id == 100  
select R;  

I would recommend using the query syntax for all parts of your query. 我建议对查询的所有部分使用查询语法。 By doing it this way, your linq query will have a more similar structure to your original sql query. 通过这种方式,您的linq查询将具有与原始SQL查询更相似的结构。 It would look like this: 它看起来像这样:

var query =
  from a in 
    (from x in DbContext.TableA
     where x.ID == 100 
     select x)
  join b in
    (from x in DbContext.TableA
     where x.ID == 100
     group x by x.Name into x
     select new
     {
       Name = x.Key,
       AnotherId = x.Max(o => o.AnotherId),
     })
  on new { a.Name, a.AnotherId } equals new { b.Name, b.AnotherId }
  select a;

saj and Raphael both have found good points: saj和Raphael都找到了好处:

.GroupBy(r => new { r.Name, r.AnotherId } )
.Select(g => new { Name = g.Name , AnotherId = g.Max(o => o.AnotherId) }))

Groups don't have a Name. 组没有名称。 Each group has a Key (and the Key has a Name and AnotherId). 每个组都有一个Key(Key有一个Name和AnotherId)。

Since you want the Max(AnotherId), you don't want to include AnotherId in your grouping Key (same as it is not present in the GroupBy clause of the original query). 由于您需要Max(AnotherId),因此您不希望在分组键中包含AnotherId(与原始查询的GroupBy子句中不存在相同)。

.GroupBy(r => r.Name)  //the Name is the Key
.Select(g => new { Name = g.Key, AnotherId = g.Max(o => o.AnotherId) }))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM