【问题标题】:Converting SQL query into LINQ - not working将 SQL 查询转换为 LINQ - 不起作用
【发布时间】: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 代码?

标签: c# sql-server linq linq-to-sql


【解决方案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
           } ;
    

    【讨论】:

      猜你喜欢
      • 2018-07-04
      • 2014-08-14
      • 1970-01-01
      • 1970-01-01
      • 2012-02-17
      • 2017-02-23
      • 2020-07-19
      • 1970-01-01
      相关资源
      最近更新 更多