如何将 Group By SQL 转换为 LINQ?
How to convert Group By SQL to LINQ?
我正在尝试将以下 SQL 语句转换为 Entity Framework。
SELECT S_NUMBER,A_NUMBER,FIRST_NAME,LAST_NAME
FROM EMPLOYEE WHERE S_NUMBER IN (
SELECT S_NUMBER
FROM EMPLOYEE
WHERE CO='ABC'
GROUP BY S_NUMBER
HAVING COUNT(*) > 1)
我已经对在 LINQ 中使用分组依据以及子查询进行了一些搜索。我将 LinqPad 与 "C# Statement" 一起使用,并根据我发现的一些示例提出了以下内容,它看起来应该可以工作。但是,在尝试将 esn.S_NUMBER 分配给匿名对象中的 sNumber 时出现错误。消息说 'IGrouping' 不包含 'S_NUMBER' 的定义。
var result = from e in EMPLOYEE
where e.CO=="ABC"
group e by e.S_NUMBER into esn
select new
{
sNumber = esn.S_NUMBER
};
result.Dump();
我的印象是所有记录基本上都会被放入一个名为 esn 的临时 table 中,我可以调用 temptable.column 名称将其分配给我的对象最终将 return 作为列表。
您想使用 Key
而不是 S_NUMBER
。分组时,结果会放入 IEnumerable<IGrouping>>
中。该分组有一个 Key
属性 保存该组的密钥,在本例中它是您的 S_NUMBER
.
select new
{
sNumber = esn.Key
};
以下查询 应该 是原始 SQL 查询的翻译。我们不使用子查询,而是分组并执行 another from...in
到 "flatten" 序列,并检查每个分组是否有一个 count > 1
就像原始查询一样。
var result = from e in EMPLOYEE
where e.CO=="ABC"
group e by e.S_NUMBER into esn
from e2 in esn
where esn.Count() > 1
select new
{
e.S_NUMBER,
e.A_NUMBER,
e.FIRST_NAME,
e.LAST_NAME
};
由于您使用一个查询的结果来过滤另一个查询,我们可以像这样对查询进行相当直接的音译:
var result =
from e in EMPLOYEE
join f in (
from fe in EMPLOYEE
where fe.CO == 'ABC'
group null by S_NUMBER into grp
where grp.Count() > 1
select grp.Key
)
on e.S_NUMBER equals f
select new { e.S_NUMBER, e.A_NUMBER, e.FIRST_NAME, e.LAST_NAME };
这不仅看起来更像原始查询,而且它的执行速度应该比其他可能更简单的形式快一点(至少在 MS SQL 上,不能代表其他人)在 LINQ 中,但在转换为 SQL 时要复杂得多...四个选择和一个交叉连接,在我的测试版本中,与两个选择和一个内部连接相比。
当然,如果您愿意,为了清楚起见,您可以将内部查询作为单独的 IQueryable
拉出:
var filter =
from e in EMPLOYEE
where e.CO == 'ABC'
group null by S_NUMBER into grp
where grp.Count() > 1
select grp.Key;
var result =
from e in EMPLOYEE
join f in filter
on e.S_NUMBER equals f
select new { e.S_NUMBER, e.A_NUMBER, e.FIRST_NAME, e.LAST_NAME };
我正在尝试将以下 SQL 语句转换为 Entity Framework。
SELECT S_NUMBER,A_NUMBER,FIRST_NAME,LAST_NAME
FROM EMPLOYEE WHERE S_NUMBER IN (
SELECT S_NUMBER
FROM EMPLOYEE
WHERE CO='ABC'
GROUP BY S_NUMBER
HAVING COUNT(*) > 1)
我已经对在 LINQ 中使用分组依据以及子查询进行了一些搜索。我将 LinqPad 与 "C# Statement" 一起使用,并根据我发现的一些示例提出了以下内容,它看起来应该可以工作。但是,在尝试将 esn.S_NUMBER 分配给匿名对象中的 sNumber 时出现错误。消息说 'IGrouping' 不包含 'S_NUMBER' 的定义。
var result = from e in EMPLOYEE
where e.CO=="ABC"
group e by e.S_NUMBER into esn
select new
{
sNumber = esn.S_NUMBER
};
result.Dump();
我的印象是所有记录基本上都会被放入一个名为 esn 的临时 table 中,我可以调用 temptable.column 名称将其分配给我的对象最终将 return 作为列表。
您想使用 Key
而不是 S_NUMBER
。分组时,结果会放入 IEnumerable<IGrouping>>
中。该分组有一个 Key
属性 保存该组的密钥,在本例中它是您的 S_NUMBER
.
select new
{
sNumber = esn.Key
};
以下查询 应该 是原始 SQL 查询的翻译。我们不使用子查询,而是分组并执行 another from...in
到 "flatten" 序列,并检查每个分组是否有一个 count > 1
就像原始查询一样。
var result = from e in EMPLOYEE
where e.CO=="ABC"
group e by e.S_NUMBER into esn
from e2 in esn
where esn.Count() > 1
select new
{
e.S_NUMBER,
e.A_NUMBER,
e.FIRST_NAME,
e.LAST_NAME
};
由于您使用一个查询的结果来过滤另一个查询,我们可以像这样对查询进行相当直接的音译:
var result =
from e in EMPLOYEE
join f in (
from fe in EMPLOYEE
where fe.CO == 'ABC'
group null by S_NUMBER into grp
where grp.Count() > 1
select grp.Key
)
on e.S_NUMBER equals f
select new { e.S_NUMBER, e.A_NUMBER, e.FIRST_NAME, e.LAST_NAME };
这不仅看起来更像原始查询,而且它的执行速度应该比其他可能更简单的形式快一点(至少在 MS SQL 上,不能代表其他人)在 LINQ 中,但在转换为 SQL 时要复杂得多...四个选择和一个交叉连接,在我的测试版本中,与两个选择和一个内部连接相比。
当然,如果您愿意,为了清楚起见,您可以将内部查询作为单独的 IQueryable
拉出:
var filter =
from e in EMPLOYEE
where e.CO == 'ABC'
group null by S_NUMBER into grp
where grp.Count() > 1
select grp.Key;
var result =
from e in EMPLOYEE
join f in filter
on e.S_NUMBER equals f
select new { e.S_NUMBER, e.A_NUMBER, e.FIRST_NAME, e.LAST_NAME };