将 SQL 查询转换为 LINQ - 不起作用
Posted
技术标签:
【中文标题】将 SQL 查询转换为 LINQ - 不起作用【英文标题】:Converting SQL query into LINQ - not working 【发布时间】:2019-08-03 22:00:56 【问题描述】:我要转换的 SQL 查询是:
select p.PhoneNumber_Id, p.State, p.Created
from PhoneNumberServiceItems p
join PhoneNumbers on p.PhoneNumber_Id = PhoneNumbers.Id
inner join (
select PhoneNumber_Id, max(Created) as MaxDate
from PhoneNumberServiceItems
group by PhoneNumber_Id
) tm on p.PhoneNumber_Id = tm.PhoneNumber_Id and p.Created = tm.MaxDate
where PhoneNumbers.NumberRangeId = Id
我最终得到的 LINQ 代码如下,但这不起作用:
var res =
from serviceItems in _db.PhoneNumberServiceItems
join nums in _db.PhoneNumbers on serviceItems.PhoneNumber_Id equals nums.Id
where nums.NumberRangeId == id
join serviceGroup in (from ps in _db.PhoneNumberServiceItems
group ps by ps.PhoneNumber_Id into numGroup
//join tm in _db.PhoneNumbers on psg.FirstOrDefault().PhoneNumber_Id equals tm.Id
select new
NumId = numGroup.FirstOrDefault().PhoneNumber_Id,
MaxDate = numGroup.Max(i => i.Created)
) on new PNId = serviceItems.PhoneNumber_Id, serviceCreated = serviceItems.Created equals new PNId = serviceGroup.NumId, serviceCreated = serviceGroup.MaxDate
select new
State = serviceItems.State,
NumId = serviceGroup.NumId,
Created = serviceGroup.MaxDate
;
我知道我的 LINQ 是错误的,但我无法确定我在做什么不同。任何帮助将不胜感激。
编辑:这是从 LINQ 生成的已编译 SQL
SELECT
[Extent1].[State] AS [State],
[Project4].[C1] AS [C1],
[Project4].[C2] AS [C2]
FROM [dbo].[PhoneNumberServiceItems] AS [Extent1]
INNER JOIN [dbo].[PhoneNumbers] AS [Extent2] ON [Extent1].[PhoneNumber_Id] = [Extent2].[Id]
INNER JOIN (SELECT
[Project3].[C1] AS [C1],
(SELECT
MAX([Extent5].[Created]) AS [A1]
FROM [dbo].[PhoneNumberServiceItems] AS [Extent5]
WHERE [Project3].[PhoneNumber_Id] = [Extent5].[PhoneNumber_Id]) AS [C2]
FROM ( SELECT
[Distinct1].[PhoneNumber_Id] AS [PhoneNumber_Id],
(SELECT TOP (1)
[Extent4].[PhoneNumber_Id] AS [PhoneNumber_Id]
FROM [dbo].[PhoneNumberServiceItems] AS [Extent4]
WHERE [Distinct1].[PhoneNumber_Id] = [Extent4].[PhoneNumber_Id]) AS [C1]
FROM ( SELECT DISTINCT
[Extent3].[PhoneNumber_Id] AS [PhoneNumber_Id]
FROM [dbo].[PhoneNumberServiceItems] AS [Extent3]
) AS [Distinct1]
) AS [Project3] ) AS [Project4] ON ([Extent1].[PhoneNumber_Id] = [Project4].[C1]) AND ([Extent1].[Created] = [Project4].[C2])
WHERE [Extent2].[NumberRangeId] = id
【问题讨论】:
怎么回事?有编译错误吗?是否检索到了错误的数据? 对不起,应该已经澄清了。当我从 LINQ 查询中查看已编译的 SQL 时,它执行的查询比我上面写的查询要密集得多。我将编辑我的帖子并将其添加进去。 为什么不直接运行 SQL? 我想知道是否有更好的方法来编写复制我在 SQL 中的内容的 LINQ 代码? 【参考方案1】:尝试以下更简单的方法:
var res = (from nums in _db.PhoneNumbers.Where(x => NumberRangeId == id)
join serviceItems in _db.PhoneNumberServiceItems on nums.PhoneNumber_Id equals serviceItems.Id
select new serviceItems = serviceItems, nums = nums)
.OrderByDescending(x => x.serviceItems.Created)
.GroupBy(x => x.nums.PhoneNumber_Id)
.Select(x => x.First())
.Select(x => new Id = x.nums.PhoneNumber_Id, state = x.serviceItems.State, maxDate = x.serviceItems.Created)
.ToList();
【讨论】:
感谢您的帮助,生成的 SQL 更加简单,但现在似乎没有带回任何数据。 LINQ 查询看起来像是在做正确的选择。 我稍微切换了查询。如果它仍然不起作用,请删除 WHERE 并查看是否有结果。【参考方案2】:这是您的查询的 linq 等效项。
var res = from s in PhoneNumberServiceItems
join p in PhoneNumbers on s.PhoneNumber_Id equals p.Id
join tm in ( from p1 in PhoneNumberServiceItems
group p1 by p1.PhoneNumber_Id into p_g
select new PhoneNumber_Id = p_g.Key,MaxDate = p_g.Max(i=> i.Created) )
on new Created = s.Created, PhoneNumber_Id = s.PhoneNumber_Id
equals new Created = tm.MaxDate, PhoneNumber_Id = tm.PhoneNumber_Id
where p.NumberRangeId == Id
select new
s.PhoneNumber_Id,
s.State,
s.Created
;
【讨论】:
【参考方案3】:var recentPhoneNos= from psi in _db.PhoneNumberServiceItems
group psi by psi .PhoneNumber_Id into psiTemp
select new
PhoneNumber_Id = psiTemp.Key,
MaxDate = psiTemp.Max(i=> i.Created)
;
var res=from serviceItems in _db.PhoneNumberServiceItems
join nums in _db.PhoneNumbers on serviceItems.PhoneNumber_Id equals nums.Id
join serviceGroup in recentPhoneNos on nums.Id equals serviceGroup .PhoneNumber_Id
where nums.NumberRangeId == id && serviceGroup.MaxDate
select new
State = serviceItems.State,
NumId = serviceGroup.NumId,
Created = serviceGroup.MaxDate
;
【讨论】:
以上是关于将 SQL 查询转换为 LINQ - 不起作用的主要内容,如果未能解决你的问题,请参考以下文章
LINQ 实体框架查询在 EF Core 中不起作用,引发异常
Linq 2 Sql - 除非在控制器内完成查询,否则存储库不起作用