我有以下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中使用Group By以及子查询进行了一些搜索。我正在使用带有“C#语句”的LinqPad,我想出了以下内容,基于一些示例,我发现它看起来应该可行。但是,我在尝试将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的临时表中,我可以调用temptable.column名称将其分配给我最终将作为列表返回的对象。
答案 0 :(得分:4)
您想使用Key
代替S_NUMBER
。分组时,结果会被放入IEnumerable<IGrouping>>
。分组具有Key
属性,该属性保存该组的密钥,在这种情况下,它是您的S_NUMBER
。
select new
{
sNumber = esn.Key
};
以下查询应该是原始SQL查询的翻译。我们不是使用子查询,而是将另一个 from...in
分组并“整理”序列,并检查每个分组是否与原始查询一样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
};
答案 1 :(得分:1)
由于您使用一个查询的结果来过滤另一个查询,我们可以像这样对查询进行相当直接的音译:
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 };
它不仅看起来更像原始查询,而且它应该比在LINQ中可能更简单的另一种形式执行得更快(至少在MS SQL上,不能为其他人说话)转换为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 };