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 };
3 Réponses :
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();
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.
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 };
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 } ;
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?