3
votes

Conversion d'une requête SQL en LINQ - ne fonctionne pas

La requête SQL que j'essaie de convertir est:

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}

Et le code LINQ avec lequel je me suis retrouvé est ci-dessous, mais cela ne fonctionne pas:

XXX

Je sais que mon LINQ est faux, mais je ne peux pas mettre le doigt sur ce que je fais différemment. Toute aide serait appréciée.

Edit: Ceci est le SQL compilé généré à partir du 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
        };


4 commentaires

En quoi est-ce «mal»? Y a-t-il une erreur de compilation? Les mauvaises données sont-elles récupérées?


Désolé, aurait dû clarifier. Lorsque je regarde le SQL conforme à partir de la requête LINQ, il fait une requête beaucoup plus intensive que celle que j'ai écrite ci-dessus. Je vais modifier mon message et l'ajouter.


Pourquoi ne lancez-vous pas simplement le SQL?


J'aimerais juste savoir s'il existe une meilleure façon d'écrire le code LINQ qui réplique ce que j'ai en SQL?


3 Réponses :


2
votes

Essayez ce qui est beaucoup plus simple:

 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();


2 commentaires

Merci pour votre aide, le SQL généré est beaucoup plus simple, mais il ne semble pas ramener de données maintenant. La requête LINQ semble cependant faire la bonne sélection.


J'ai changé un peu la requête. Si cela ne fonctionne toujours pas, supprimez le WHERE et voyez si vous obtenez des résultats.



2
votes

Ceci est l'équivalent linq de votre requête.

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
                    };


0 commentaires

1
votes
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
       } ;

0 commentaires